标签:
今天,是个好日子。我终于写出第一个采用动态规划方法的程序了,虽然之前听别人讲过这个例子,但现在只是记住了状态转移方程。
自己动手写程序,就是不一样。Cheers!
#include <stdio.h> #include <stdlib.h> #include <string.h>
//本题的状态转移方程为: f[i] = max(a[i], f[i-1]+a[i])
//这里递归转换迭代的方法是先算小值,再利用小值计算大值
struct seg{ int l, r; }; struct seg pos[100010]; int f[100010]; int main(void) { int nline, icase = 1, m; scanf("%d", &nline); memset(pos, 0, sizeof(struct seg) * 100010); memset(f, -99999, sizeof(int) * 100010); m = nline; while(m--) { int i, n; int a[100010]; int max; scanf("%d", &n); for(i = 1; i < n + 1; i++) { scanf("%d", &a[i]); } f[1] = a[1]; pos[1].l = pos[1].r = 1; //初始化第一个元素的左边界和右边界 for(i = 2; i < n + 1; i++) { if(a[i] > f[i-1] + a[i]) { f[i] = a[i]; pos[i].l = pos[i].r = i; //同时更新左边界和右边界 } else { f[i] = f[i-1] + a[i]; pos[i].l = pos[i-1].l; //保留前一个元素的左边界 pos[i].r = i; //更新右边界 } } max = f[1]; for(i = 2; i < n + 1; i++) { //找到子序列的最大值 if(f[i] > max) max = f[i]; } printf("Case %d:\n", icase++); printf("%d ", max); for(i = 1; i < n + 1; i++) { //找到子序列的最大值所处的左边界和右边界 if(f[i] == max) printf("%d %d\n", pos[i].l, pos[i].r); } if(icase != nline + 1) printf("\n"); } }
标签:
原文地址:http://www.cnblogs.com/mylinuxer/p/4326559.html