传送门
先喷一波出题人
“第P+T-1分钟结束”应该改为“第P+T-1分钟末结束”
还有工作时间是在 第N分钟末 结束
不然这题样例都是错的
解法:
考虑dp
因为要优先选先来的任务
所以正着搜有后效性
于是考虑倒着搜
设dp[i]为第i分钟初到第n分钟末最多可以休息的时间
则用任务时间作为转移条件
若第i分钟有任务开始
则 dp[i]=dp[i+len[j]] (len表示任务时间,j表示任务标号)
否则 dp[i]=dp[i+1]+1
最后dp[1]即为答案
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#define inf 2000000000
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
int n,m,dp[10010];
int len[10010],head[10010],nxt[10010],tot=0;
void add(int p,int l)
{
len[++tot]=l;
nxt[tot]=head[p];
head[p]=tot;
}
int main()
{
scanf("%d%d",&n,&m);
rep(i,1,m)
{
int p,l;
scanf("%d%d",&p,&l);
add(p,l);
}
dwn(i,n,1)
{
if(!head[i]) dp[i]=dp[i+1]+1;
else
{
for(int j=head[i];j;j=nxt[j])
{
dp[i]=max(dp[i],dp[i+len[j]]);
}
}
}
printf("%d
",dp[1]);
return 0;
}