现在的位置: 首页 > 综合 > 正文

hdu 1003 基础dp:最大字连续子串和

2018年04月23日 ⁄ 综合 ⁄ 共 836字 ⁄ 字号 评论关闭

背景:感受到了,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;
}

抱歉!评论已关闭.