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 }