题解:
考虑我们休息的时间一定在连续的一段,因此我们可以忽略走连续的一段;
但直接这样做并不对,因为前面会有影响(比如前面有一段通话占的时间很长,把后面时间挤掉了)
我们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 }