PAT甲級(jí)A1007---動(dòng)態(tài)規(guī)劃最大連續(xù)子序列和

1007 Maximum Subsequence Sum (25分)

1007.png
分析:

本題要求最大連續(xù)子序列的和,輸出最大之和以及子序列第一個(gè)數(shù)和最后一個(gè)數(shù)。如果方案不唯一,則輸出i,j最小的一組。如果所有數(shù)都是負(fù)數(shù),則最大和為0,然后輸出首尾元素。
先考慮如何求最大和。以dp[i]表示以A[i]作為末尾的連續(xù)序列最大和。以本題為樣例dp[0]=-10,dp[1]=1,dp[2]=3......容易知狀態(tài)轉(zhuǎn)移方程為dp[i]=max{A[i],dp[i-1]+A[i]}。通過遍歷就可通過dp[0]把所有dp求出來,最大和就是dp數(shù)組中最大的數(shù)。
再考慮如何求最大連續(xù)子序列的首位元素,以s[i]表示以A[i]作為結(jié)尾的最大連續(xù)子序列是從哪個(gè)元素開始,根據(jù)狀態(tài)轉(zhuǎn)移方程易知s[i]=i或者s[i]=s[i-1]。
在一開始的時(shí)候先考慮所有數(shù)是負(fù)數(shù)的情況,節(jié)省時(shí)間。

C++:
#include <cstdio>

const int maxn = 10010;

int arr[maxn], dp[maxn], s[maxn];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    //先處理全為負(fù)數(shù)的情況
    bool flag = false; //是否有正數(shù)
    for (int i = 0; i < n; i++) {
        if (arr[i] >= 0) {
            flag = true;
            break;
        }
    }
    if (flag == false) {
        printf("0 %d %d\n", arr[0], arr[n - 1]);
        return 0;
    }
    dp[0] = arr[0];
    s[0] = 0;
    for (int i = 1; i < n; i++) {
        if (dp[i - 1] + arr[i] > arr[i]) {
            dp[i] = dp[i - 1] + arr[i];
            s[i] = s[i - 1];
        } else {
            dp[i] = arr[i];
            s[i] = i;
        }
    }
    int index = 0;//dp數(shù)組最大值的下標(biāo)
    for (int i = 1; i < n; i++) {
        if (dp[i] > dp[index]) {
            index = i;
        }
    }
    printf("%d %d %d\n", dp[index], arr[s[index]], arr[index]);
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容