P1280 尼克的任务

时间:2019-04-18
本文章向大家介绍P1280 尼克的任务,主要包括P1280 尼克的任务使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
  • 题目

  • 分析

题目要求最大的空暇时间。

DP要逆序推。

dp[ i ] 代表,从第 i 分钟,开始工作,能够得到的最大的空暇时间。

 

说简单点,就是

如果正着推,就是dp[ i ] 代表从1到 i 分钟的空暇时间,你不知道 i 分钟之后会发生什么,第 i 分钟要不要接活,也不知道最优结果。怎么能够进行递推呢?

 所以,选择逆序。

这里,有个很好的讲解:对样例的清晰解释

8  -- 存在两个起始任务,取最大值Max( 2,3 ) -- 3

解释一下 Max(2,3) 其实是= Max(dp[8+1],dp[8+5])  1和5是第8分钟开始的任务的持续时间。那8+1,8+5就是第8分钟开始的任务的结束时间。


  •  代码


//P1280
#include<iostream>
#include<algorithm>
#include<set>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#include<stdio.h>
using namespace std;
#define ll long long

const int maxn=1e5+5;
struct Task
{
	int start;
	int period;
}task[maxn];
bool mark[maxn];
vector<int>v[maxn];

int dp[maxn];


int main()
{
	int n,k;
	scanf("%d%d",&n,&k);
	memset(mark,false,sizeof(mark));
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d",&task[i].start,&task[i].period);
		mark[task[i].start]=true;
	}

//	for(int i=1;i<=k;i++)
//	cout<<task[i].start<<" "<<task[i].period<<endl;
	memset(dp,0,sizeof(dp));
	dp[n+1]=0;
	
	for(int i=n;i>=1;i--)
	{
		if(mark[i]==false)
			dp[i]=dp[i+1]+1;
		else
		{
			for(int j=1;j<=k;j++)
			{
				if(mark[task[j].start]==true && task[j].start==i)
				{
				//	cout<<i+task[j].period<<'*'<<task[j].start<<'*'<<dp[i+task[j].period]<<endl;
					dp[i]=max(dp[i],dp[i+task[j].period]);
				}
					
			}
		}
	//	printf("dp[%d]=%d\t",i,dp[i]);
	}
	//cout<<endl;
	cout<<dp[1]<<endl;
	
}

我这个内层for循环debug了很久,因为忘了判断 第k个任务的开始时间和当前时间相同。。。。