【codevs4829】數字三角形++
阿新 • • 發佈:2018-11-21
題目大意:給定一個數字三角形,求從 (1,1) 到第 N 行的路徑經過的權值之和加上該路徑上任意一個點的權值之和的最大值。
題解:任意加一條路徑上的某個值,可以看成是多了一次選擇的權利,即:在每次經過一個點時,若沒使用過權利,可以選擇使用或者不使用,若已經使用過,則不能再使用。因此有狀態 \(dp[i][j][0/1]\)表示經過前 i 行,位置在 (i,j) 時,是否用過這次權利。
程式碼如下
#include <bits/stdc++.h> using namespace std; const int maxn=1010; inline int read(){ int x=0,f=1;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch)); do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch)); return f*x; } int n,ans,mp[maxn][maxn],dp[maxn][maxn][2]; void read_and_parse(){ n=read(); for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) mp[i][j]=read(); dp[1][1][0]=mp[1][1],dp[1][1][1]=mp[1][1]<<1; } void solve(){ for(int i=1;i<n;i++) for(int j=1;j<=i;j++){ dp[i+1][j][0]=max(dp[i+1][j][0],dp[i][j][0]+mp[i+1][j]); dp[i+1][j][1]=max(dp[i+1][j][1],max(dp[i][j][1]+mp[i+1][j],dp[i][j][0]+(mp[i+1][j]<<1))); dp[i+1][j+1][0]=max(dp[i+1][j+1][0],dp[i][j][0]+mp[i+1][j+1]); dp[i+1][j+1][1]=max(dp[1+1][j+1][1],max(dp[i][j][1]+mp[i+1][j+1],dp[i][j][0]+(mp[i+1][j+1]<<1))); } for(int i=1;i<=n;i++)ans=max(ans,dp[n][i][1]); printf("%d\n",ans); } int main(){ read_and_parse(); solve(); return 0; }