codeforces 158E Phone Talks (dp)

来源:互联网 发布:域名怎么交易 编辑:程序博客网 时间:2024/06/08 03:47

题意:

麦克是个名人每天都要接n电话,每通电话给出打来的时间和持续时间,麦克可以选择接或不接,但是只能不接k通电话。如果某通电话打来时麦克正在打电话他可以选择让电话排队,或者忽略不接。当麦克空闲时首先从排队的第一个打来的电话开始接起。麦克是个很懒的人,所以需要大量的睡觉,但是睡觉的时间必须是连续的,因此要求出麦克能睡觉的最大连续时间。

题解:

一开状态想错了,想成了dp[i][j][2]前i个电话接j个电话0 1 分别表示这通电话接还是不接。

正确dp[i][j]表示前i通电话放弃了j通的最早结束电话的时间,然后在定义一个ans变量时刻更行最大的的中间空闲的时间。

最后用一天最迟的时间减去dp[n][j]和ans比较得出最大连续睡觉时间。


#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<map>using namespace std;typedef long long lld;const int oo=0x3f3f3f3f;const lld OO=1e18;const int Mod=1000000007;const int maxn=4005;int ans,dp[maxn][maxn];int t[maxn],d[maxn];int main(){    int n,k;    while(scanf("%d %d",&n,&k)!=EOF)    {        for(int i=1;i<=n;i++)            scanf("%d %d",&t[i],&d[i]);        memset(dp,0x3f,sizeof dp);        dp[0][0]=1;        ans=0;        for(int i=0;i<n;i++)        {            for(int j=0;j<=k;j++)            {                if(j!=k)                    dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);                if(dp[i][j]<t[i+1])                {                    ans=max(t[i+1]-dp[i][j],ans);                    dp[i+1][j]=min(dp[i+1][j],t[i+1]+d[i+1]);                }                else                    dp[i+1][j]=min(dp[i+1][j],dp[i][j]+d[i+1]);            }        }        for(int i=0;i<=k;i++)            ans=max(ans,86401-dp[n][i]);        printf("%d\n",ans);    }    return 0;}



0 0
原创粉丝点击