-
题目
-
分析
题目要求最大的空暇时间。
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个任务的开始时间和当前时间相同。。。。