背景:感受到了,dp的进化就是找到转移方程,而这都需要练习一定量的题来找感觉。
思路:1.动态规划:
转移方程:
F[i]=max{F[i-1]+a[i],a[i]} //F[i]表示以i结尾的字串的最大和,a[i]是第i个数的值<span id="transmark"></span>
这里把"以i结尾的最大字串和"作为状态十分巧妙,这样就能实现,一个接一个的人转移了,因为都是结尾,只需要考虑选不选当前一个,如果以i-1结尾的最大连续字串和大于0则以i结尾的最大连续字串和就是F[i-1] + a[i],否则就是a[i]。dp的本质记忆搜索中已经计算过的,避免重复计算,但是只具有这个思想,距离找到具体的转移方程还是需要巧妙的思维。这个题的主要思维是这样的转移方程才具有可转移性。
2.贪心思想也是可以的,以当前数字结尾的字串如果为负就,把下一数当做开头,继续找,实质看来和动态规划一样。
我的代码:
//hdu 1003 #include<cstdio> #include<iostream> using namespace std; int a[100009],F[100009]; int main(void){ int t,n,x,y,start,end,max; scanf("%d",&t); for(int k=1;k <= t;k++){ scanf("%d",&n); for(int i=1;i <= n;i++) scanf("%d",&a[i]); F[0]=0; max=-1e9; start=end=x=y=1; for(int i=1;i <= n;i++){ if(F[i-1]+a[i] < a[i]) {x=i;y=i;F[i]=a[i];} else {F[i]=F[i-1]+a[i];y=i;} if(F[i] > max){ start=x; end=y; max=F[i]; } } if(k-1) printf("\n"); printf("Case %d:\n%d %d %d\n",k,max,start,end); } return 0; }