HDU1003解题报告

给定一串数字,要求子序列和最大的值。这个子序列是连续的。要不然,就直接选取全是正值的加和即可。我开始很直接的就想到一个O(n^2)的算法,因为子序列又开始位置i和结束位置j。我就定义了一个二维数组,索引就是位置,例如,a[i][j]表示,子序列i到j的和,然后遍历一边二维数组,得到最大的值。代码如下:

#include 
using namespace std;

int main() {
    int t, n, a[100001];
    cin >> t;
    int index = 1;
    while (index <= t) {
        cin >> n;

        for (int i = 1; i <= n; ++i)
            cin >> a[i];
        int max = -100000001, x = -1, y = -2, last = -1;
        for (int i = 1; i <= n; ++i)
            for (int j = i; j <= n; ++j) {
                int tmp = -1;
                if (i == j) {
                    tmp = a[i];
                } else
                    tmp = last + a[j];
                if (tmp > max) {
                    max = tmp;
                    x = i;
                    y = j;
                }
                last = tmp;
            }
        cout << "Case " << index << ":" << endl;
        cout << max << " " << x << " " << y;
        if (index != t)
            cout << endl;
        ++index;
    }
    return 0;
}

O(n^2)我自己也没想着能过,所以采用动态规划改进,递归形式很简单,如下:

 dp[i] = max(dp[i - 1], a[i])------(1)

很简单,不解释。同时需要使用s和e数组存储每个d[i]的起始位置。具体实现代码如下:

#include 
using namespace std;

int main() {
    int t, n;
    cin >> t;
    int index = 1;
    while (index <= t) {
        cin >> n;
        int a[n + 1], dp[n + 1], s[n + 1], e[n + 1];
        for (int i = 1; i <= n; ++i)
            cin >> a[i];
        dp[0] = 0;
        s[0] = 1;
        for (int i = 1; i <= n; ++i) {
            int tmp = dp[i - 1] + a[i];
            if (tmp >= a[i]) {
                dp[i] = tmp;
                s[i] = s[i - 1];
            } else {
                dp[i] = a[i];
                s[i] = i;
            }
            e[i] = i;
        }
        int max = -100000001, x = -1, y = -1;
        for (int i = 1; i <= n; ++i) {
            if (dp[i] > max) {
                max = dp[i];
                x = s[i];
                y = e[i];
            }
        }
        cout << "Case " << index << ":" << endl;
        cout << max << " " << x << " " << y << endl;
        if (index != t)
            cout << endl;
        ++index;
    }
    return 0;
}

posted on 2012-02-01 23:47  sing1ee  阅读(141)  评论(0)    收藏  举报