洛谷 P1280 尼克的任务(dp)

传送门


解题思路

因为正序不好推,所以我们倒序:

dp[i]表示从时间i到最终时刻n的最大休息时间,所以我们可以推出以下的状态转移方程:

  • 若i时刻无任务,则dp[i]=dp[i+1]+1;
  • 若i时刻有至少一个任务,则枚举这些任务k,dp[i]=dp[a[k]+b[k]];(a,b为题目中读入的每个任务的起始时间和时长)。

最终答案即为dp[1]。

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=10005;
 5 int n,t,dp[maxn],cnt=1;
 6 struct node{
 7     int b,e,w;
 8 }a[maxn];
 9 bool cmp(node x,node y){
10     return x.b!=y.b?x.b>y.b:x.e<y.e;
11 }
12 int main(){
13     cin>>n>>t;
14     for(int i=1;i<=t;i++){
15         cin>>a[i].b>>a[i].w;
16         a[i].e=a[i].b+a[i].w-1;
17     }
18     sort(a+1,a+t+1,cmp);
19     for(int i=n;i>=1;i--){
20         if(cnt>t||a[cnt].b<i) dp[i]=dp[i+1]+1;
21         else{
22             while(cnt<=t&&a[cnt].b>=i) dp[i]=max(dp[i],dp[a[cnt++].e+1]);
23         }
24     }
25     cout<<dp[1];
26     return 0;
27 } 
原文地址:https://www.cnblogs.com/yinyuqin/p/13829144.html