HDU-1003 Max Sum 动态规划

这次看了这题的动态规划写法,顿时觉得好理解多了。

这里要对dp[i]的意义进行一下说明,dp[i]表示从1~i包含第i个数的最大子串和,如果前i-1个数的包含i-1在内的最大和为正数的话,那么包含第i个数的最大子串和就是dp[i-1]+seq[i],否则dp[i] 就等于seq[i]了。

该题的动态递归写法并没有直接给出最终答案的状态,但是却能够根据另外的状态推到出答案。这点值得我们思考。

代码如下:

#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#define MAXN 100005
using namespace std;

int N, dp[MAXN], seq[MAXN], p[MAXN], begin, end;

inline int max(int x, int y)
{
    return x > y ? x : y;
}

void DP(int &Max)
{
    memset(dp, 0, sizeof (dp));
    dp[1] = seq[1];
    Max = dp[1];
    begin = end = 1;
    for (int i = 2; i <= N; ++i) {
        dp[i] = max(dp[i-1]+seq[i], seq[i]);
        if (dp[i-1] >= 0) {
            p[i] = p[i-1];
        }
        if (Max < dp[i]) {
            begin = p[i];
            end = i;
            Max = dp[i];
        }
    }
}

int main()
{ 
    int T, ans;
    scanf("%d", &T);
    for (int ca = 1; ca <= T; ++ca) {
        scanf("%d", &N);
        for (int i = 1; i <= N; ++i) {
            scanf("%d", &seq[i]);
            p[i] = i;
        } 
        printf("Case %d:\n", ca);
        DP(ans);
        printf("%d %d %d\n", ans, begin, end);
        if (ca != T) {
            puts("");
        }
    }
    return 0;
}

你可能感兴趣的:(动态规划)