codeforces 158E

题解:

考虑我们休息的时间一定在连续的一段,因此我们可以忽略走连续的一段;

但直接这样做并不对,因为前面会有影响(比如前面有一段通话占的时间很长,把后面时间挤掉了)

我们dp[i][j]表示到第i个电话忽略了j个的最短结束时间,转移就行

然后我们枚举状态,从结束的i开始选k-j个删掉,算一下答案取最大就行了。

 1 #include<bits/stdc++.h>
 2 #define maxn 4005
 3 using namespace std;
 4 int n,k;
 5 int t[maxn],d[maxn];
 6 int dp[maxn][maxn];
 7 int main()
 8 {
 9     scanf("%d%d",&n,&k);
10     for(int i=1;i<=n;++i)scanf("%d%d",&t[i],&d[i]);
11     n++;t[n]=86401;
12     for(int i=1;i<=n;++i)
13     {
14         for(int j=0;j<=min(i,k);++j)
15         {
16             if(!j)dp[i][j]=max(dp[i-1][j]+d[i],t[i]+d[i]-1);
17             else dp[i][j]=min(max(dp[i-1][j]+d[i],t[i]+d[i]-1),dp[i-1][j-1]);
18         }
19     }
20     int ans=0;
21     for(int i=0;i<n;++i)
22     {
23         for(int j=0;j<=min(i,k);++j)
24         {
25             int p=k-j;
26             ans=max(ans,t[min(n,i+p+1)]-dp[i][j]-1);
27         }
28     }
29     printf("%d
",ans);
30     return 0;
31 }
View Code
原文地址:https://www.cnblogs.com/uuzlove/p/10508166.html