暑假终于要到了,虽然成绩炸掉了,但是学oi还是得继续呀……
解:
对于本题,又是一道经典的线性dp问题。首先考虑设计状态:
设dp[i]是i到n时间中休息时间最长的时间,则最后答案就是dp[1]
对于此状态,我们有:
1.当此时没有任务,则dp[i]=dp[i+1]+1,即上一时刻的最长休息时间加上当前时刻
2.当时有任务,则dp[i]=max(dp[i],dp[i+q[num].t]),即选择第num个任务的最大休息时间,q[num].t表示num任务的时间。
实现细节请看代码:
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; struct node{ ll s,e; }q[500000]; ll n,k,dp[500000]; ll S[500000],num=1; inline bool cmp(node a,node b){ return a.s>b.s; } int main(){ scanf("%lld%lld",&n,&k); for(ll i=1;i<=k;++i){ scanf("%lld%lld",&q[i].s,&q[i].e); S[q[i].s]++; }sort(q+1,q+k+1,cmp); for(ll i=n;i>=1;i--){ if(S[i]==0)dp[i]=dp[i+1]+1; else{ for(ll j=1;j<=S[i];j++){ dp[i]=max(dp[i],dp[i+q[num].e]); num++; } } }printf("%lld\n",dp[1]); return 0; }
最近dp的文章应该会比较多,为暑假夏令营做准备吧