就这样A了……
我的思路大致是:
获得生活费与花费的差(在纸上演练一下就清楚为什么了),
这一题是求序列和要大于等于0的最长子序列,并且该序列的第一个值必须>=0,
还有一个地方就是这是一个圆圈,即从第N个数可以回头转到第一个值,但是最多也就是转一圈,即将该序列浏览两遍,
但是转到第一个值的条件是dp[n] > 0,因为只有最后一个dp值大于0的时候转到前面才有意义,试问,如果最后一个dp值小于等于0,都已经欠钱了,早就被踢出德国了……
然后为了方便可以将dp[n]存在dp[0]里面……
还有一个问题是浏览第一遍数组时,如果所得值已经大于n了,就没有必要继续了,给maxn直接赋值n就可以退出循环了……
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 4 int dp[100000+10]; 5 int inp[100000+10]; 6 7 int main() 8 { 9 int n; 10 11 while(scanf("%d",&n) == 1) 12 { 13 int t = 0; 14 for(int i = 1;i <= n;i ++) 15 { 16 int p,r; 17 scanf("%d%d",&p,&r); 18 inp[i] = p - r; 19 if(inp[i] < 0) 20 t ++; 21 } 22 23 if(t == n) 24 { 25 printf("0\n"); 26 continue; 27 } 28 int maxn = 0; 29 int num = 1; 30 31 //dp[0] = 0; 32 int flag = 1; 33 int i; 34 for(int j = 1;j <= 2 * n;j ++) 35 { 36 if(j == n + 1) 37 { 38 if(dp[n] <= 0) 39 break; 40 dp[0] = dp[n]; 41 flag = 0; 42 } 43 if(j > n) 44 i = j % n; 45 else 46 i = j; 47 if(flag && inp[i] < 0) 48 continue; 49 50 if(flag) 51 { 52 dp[i] = inp[i]; 53 flag = 0; 54 } 55 else 56 { 57 if(dp[i-1] + inp[i] >= 0) 58 { 59 num ++; 60 dp[i] = dp[i-1] + inp[i]; 61 flag = 0; 62 if(num > n) 63 { 64 maxn = n; 65 break; 66 } 67 } 68 else 69 { 70 flag = 1; 71 num = 1; 72 } 73 if(num > maxn) 74 maxn = num; 75 } 76 77 } 78 79 printf("%d\n",maxn); 80 } 81 82 return 0; 83 }