CCF-CSP认证 202212-2训练计划

题目描述

思路

首先需要注意题目中的一些地方:天数是从1开始计数的,每个科目最多只依赖一个其它科目且依赖科目的编号必须小于自己,如果在n天内不能完成就不需要输出最晚开始时间。

求最早开始时间,要分为两种情况(关键在于当前科目是否有依赖):如果当前科目没有依赖,则最早开始时间就为1;如果当前科目有依赖,则最早开始时间为所依赖科目的最早开始时间+所依赖科目完成所需的时间,即earlyres[i]=earlyres[pre[i]]+days[pre[i]]。

求最晚开始时间,即最后一个科目完成时,恰好是最后一天,才能满足最晚开始时间的要求。需要从最后一个项目往前开始遍历(题目中指出:每项科目最多只依赖一项别的科目,且满足依赖科目的编号小于自己),如果当前项目没有依赖项目,则最晚开始时间只需要保证该科目可以按时完成,即lateres[i] =n-days[i]+1;如果当前科目有依赖,则需要对依赖项目的最晚开始时间进行更新,取最小值min(lateres[pre[i]],lateres[i]-days[pre[i]]),且开始需要将lateres数组值初始化为极大。

代码

C++版:

#include <bits/stdc++.h>

using namespace std;

const int N = 110;
int n,m; // 距离大赛开幕的天数,训练科目数量 
int pre[N];
int days[N];
int earlyres[N];
int lateres[N];

int main(){
	int latest=0;
	cin>>n>>m; 
	for(int i=1;i<=m;i++){
		cin>>pre[i];
	}
	for(int i=1;i<=m;i++){
		cin>>days[i];
	}
	for(int i=1;i<=m;i++){
		if(pre[i]==0) earlyres[i]=1;
		else earlyres[i]=earlyres[pre[i]]+days[pre[i]]; // 最早开始时间
		latest=max(latest,earlyres[i]+days[i]-1);// 判断能够全部完成训练,需要记录最后一项科目的完成时间
	}
	for(int i=1;i<=m;i++){
		cout<<earlyres[i]<<" ";
	}
	cout<<endl;
	if(latest>n) return 0;
	memset(lateres,0x3f,sizeof(lateres)); // 初始化为无穷大
	 
	for(int i=m;i>0;i--){
		if(lateres[i]>n) lateres[i]=n-days[i]+1; // 最晚开始时间 
		if(pre[i]!=0) lateres[pre[i]]=min(lateres[pre[i]],lateres[i]-days[pre[i]]); // 更新依赖节点的最晚开始时间 
	}
	for(int i=1;i<=m;i++){
		cout<<lateres[i]<<" ";
	}
	cout<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值