Codeforces 158E Phone Talks

http://codeforces.com/contest/158/problem/E

题目大意:

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

思路:dp[i][j]代表前i个电话,不听j个的最少时间,然后枚举即可

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 struct node{
 7     int t,d;
 8 }p[200005];
 9 int n,m,f[5005][5005];
10 bool cmp(node a,node b){
11     return a.t<b.t;
12 }
13 int read(){
14     int t=0,f=1;char ch=getchar();
15     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
16     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
17     return t*f;
18 }
19 int main(){    
20     n=read();m=read();
21     for (int i=0;i<n;i++) p[i].t=read(),p[i].d=read();
22     std::sort(p,p+n,cmp);
23     p[n].t=86401;
24     f[0][1]=0;
25     f[0][0]=p[0].t+p[0].d-1;
26     if (m==n){
27         printf("86400");
28         return 0;
29     }
30     for (int i=1;i<n;i++){
31         f[i][0]=std::max(p[i].t-1,f[i-1][0])+p[i].d;
32         for (int j=1;j<=m&&j<=i;j++){
33             int xx=p[i].t-1;
34             if (i-1>=j) xx=std::max(xx,f[i-1][j]);
35             f[i][j]=std::min(f[i-1][j-1],xx+p[i].d);
36         }
37     }
38     int ans=0;
39     for (int i=0;i<n;i++)
40      for (int j=0;j<=m;j++){
41             int x=std::min(n,m-j+i+1);
42             ans=std::max(ans,p[x].t-1-f[i][j]);
43      }
44     printf("%d\n",ans);
45     return 0;
46 }

 

posted @ 2016-06-28 22:00  GFY  阅读(308)  评论(0编辑  收藏  举报