SCU 1114 數字三角 動態規劃 保存路徑

解題報告:

思路:我採用的是從下往上遞推,那麼dp[0][0]就是答案,遞推式爲:dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + num[i][j]。顯然最後一行要單獨處理。對於路徑:可以定義一個三維數組path,用來記錄當前點從哪個點轉移過來的,第三維爲0記錄的是x座標,爲1記錄y座標。

代碼:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const ll N = 100 + 10;

ll num[N][N];
ll dp[N][N], path[N][N][2];
ll n;

void solve(){
    memset(dp, 0, sizeof(dp));
    for(ll i=0; i<n; ++i){
        dp[n-1][i] = num[n-1][i];
        path[n-1][i][0] = -1;
        path[n-1][i][1] = -1;
    }
    for(ll i=n-2; i>=0; --i){
        for(ll j=0; j<=i; ++j){
            if(dp[i+1][j] > dp[i+1][j+1]){
                dp[i][j] = dp[i+1][j] + num[i][j];
                path[i][j][0] = i+1;
                path[i][j][1] = j;
            }else {
                dp[i][j] = dp[i+1][j+1] + num[i][j];
                path[i][j][0] = i+1;
                path[i][j][1] = j+1;
            }
        }
    }
    printf("%lld\n", dp[0][0]);
    printf("%lld", num[0][0]);
    ll x = 0, y = 0;
    while(true){
        ll xx = x, yy = y;//下面賦值會改變x
        x = path[xx][yy][0];
        y = path[xx][yy][1];
        if(x == -1 || y == -1)break;
        printf(" %lld", num[x][y]);
    }
    puts("");
}

int main(){
    while(~scanf("%lld", &n)){
        for(ll i=0; i<n; ++i){
            for(ll j=0; j<=i; ++j){
                scanf("%lld", &num[i][j]);
            }
        }
        solve();
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章