POJ 2938 Economic Phone Calls( DP SDUT 2368)

题目链接

这个题的状态转移什么的和题意比起来,根本不算什么。。。根本看不懂啊,昨天比赛大体看懂了,以为是每一年的都要保存其实是从第一个+开始保存每一年的电话。中间改了

N多的BUG,终于在知道正确的题意后,改了最后一个BUG,AC了!!!

题意:一个手机的电话记录太多了要删除以前的记录,+ 是必须要留下的,这个手机没法显示年份,所以要从月份啥的推断,从第一个+ 开始保存,并且可以通过电话的时间分辨出年份。有很多细节要注意,WA了N次啊。。。

所以 dp[i] 上个电话是j,则 j的年份一定和i一样,或者在i的前一年并且j的时间>=i的时间,当然如果存在 + 的电话,j一定是+电话,如果没有则取小。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <math.h>
  4 #define N 1000000000
  5 int o[1001],p[1001],dp[1001];
  6 int s[1001][5];
  7 char nn[1001][100],ji[5];
  8 int judge(int x,int y)
  9 {
 10     int i;
 11     for(i = 1; i <= 4; i ++)
 12     {
 13         if(s[x][i] > s[y][i])
 14             return 1;
 15         else if(s[x][i] < s[y][i])
 16             return 0;
 17     }
 18     return 2;
 19 }
 20 int main()
 21 {
 22     int n,i,j,num,min,str;
 23     while(scanf("%d%*c",&n)!=EOF)
 24     {
 25         num = 0;
 26         if(!n) break;
 27         memset(dp,0,sizeof(dp));
 28         memset(o,0,sizeof(o));
 29         memset(p,0,sizeof(p));
 30         for(i = 1; i <= n; i ++)
 31         {
 32             scanf("%d:%d:%d:%d%s%s",&s[i][1],&s[i][2],&s[i][3],&s[i][4],nn[i],ji);
 33             if(ji[0] == '+')
 34                 o[i] = 1;
 35         }
 36         num = 1;
 37         p[1] = 1;
 38         for(i = 2; i <= n; i ++)
 39         {
 40             if(judge(i-1,i))
 41             {
 42                 num ++;
 43                 p[i] = num;
 44             }
 45             else
 46             {
 47                 p[i] = num;
 48             }
 49         }
 50         for(i = 1; i <= n; i ++)
 51         {
 52             if(o[i])
 53             {
 54                 str = i;
 55                 break;
 56             }
 57         }
 58         for(i = str; i <= n; i ++)
 59         {
 60             min = N;
 61             for(j = i-1; j >= str-1; j --)
 62             {
 63                 if(p[j] < p[i]-1)
 64                     break;
 65                 if(j == str-1)
 66                 {
 67                     min = 0;
 68                     break;
 69                 }
 70                 if(p[j] == p[i]-1&&judge(i,j) == 1)
 71                     break;
 72                 if(o[j])
 73                 {
 74                     min = dp[j];
 75                     break;
 76                 }
 77                 if(min > dp[j])
 78                     min = dp[j];
 79             }
 80             dp[i] = min+1;
 81         }
 82         min = dp[n];
 83         if(!o[n])
 84         {
 85             for(i = n-1; i >= 1; i --)
 86             {
 87                 if(p[i] != p[n])
 88                     break;
 89                 if(min > dp[i])
 90                 {
 91                     min = dp[i];
 92                 }
 93                 if(o[i])
 94                 break;
 95             }
 96         }
 97         printf("%d\n",min);
 98     }
 99     return 0;
100 } 
posted @ 2012-08-29 10:47  Naix_x  阅读(373)  评论(0编辑  收藏  举报