这是一道简单的DP(dynamic programing)问题。计算最大子序列。
在解题时需要注意考虑完全,还有就是算法的完整程度。
可以用这两个去测试完整度:-1,-2,-3,-4,-5;0,0,0,0,0
在计算中需要使用到动态规划的状态以及状态转移方程。
在这题中,状态是子序列的和,状态转移方程是,某个数与以某个数结尾的子序列中的最大子序列的大小比较
1 for(i = 1;i < n;i++){ 2 if(num[i] > d[i - 1] + num[i]){//如果num[i]大于num[i] + d[i - 1](状态),那就不用考虑状态,直接进行状态转移 3 endex[i] = index[i] = i + 1; 4 d[i] = num[i]; 5 } 6 else{//反之,继续累计 7 endex[i] = i + 1; 8 index[i] = index[i - 1]; 9 d[i] = d[i - 1] + num[i]; 10 } 11 }
贴上AC代码:
#include<stdio.h> #include<stdlib.h> int main(){ int i = 0; int n = 0; int r = 0; int max; int maxi = 0; int maxe = 0; int casen = 0; int *num; int *d,*index,*endex; scanf("%d",&casen); while(casen --) { if(r) printf(" "); scanf("%d",&n); num = (int *)malloc(sizeof(int) * n);//动态开辟内存,避免空间不足 d = (int *)malloc(sizeof(int) * n); index = (int *)malloc(sizeof(int) * n); endex = (int *)malloc(sizeof(int) * n); for(i = 0 ;i < n;i ++){ scanf("%d",&num[i]); } index[0] = 1; endex[0] = 1; d[0] = num[0]; for(i = 1;i < n;i++){ if(num[i] > d[i - 1] + num[i]){ endex[i] = index[i] = i + 1; d[i] = num[i]; } else{ endex[i] = i + 1; index[i] = index[i - 1]; d[i] = d[i - 1] + num[i]; } } max = d[0]; maxi = 1; maxe = 1; for(i = 1;i < n;i ++){ if(max < d[i]){ max = d[i]; maxi = index[i]; maxe = endex[i]; } } r ++; printf("Case %d: ",r); printf("%d %d %d ",max,maxi,maxe); } return 0; }
THISSKY出品,原文链接:http://www.cnblogs.com/zhuhongjongy/p/4948594.html