51Nod 1084 矩陣取數問題 V2(dp降維)
阿新 • • 發佈:2018-11-23
一個M*N矩陣中有不同的正整數,經過這個格子,就能獲得相應價值的獎勵,先從左上走到右下,再從右下走到左上。第1遍時只能向下和向右走,第2遍時只能向上和向左走。兩次如果經過同一個格子,則該格子的獎勵只計算一次,求能夠獲得的最大價值。
例如:3 * 3的方格。
1 3 3
2 1 3
2 2 1
能夠獲得的最大價值為:17。1 -> 3 -> 3 -> 3 -> 1 -> 2 -> 2 -> 2 -> 1。其中起點和終點的獎勵只計算1次。
Input
第1行:2個數M N,中間用空格分隔,為矩陣的大小。(2 <= M, N <= 200) 第2 - N + 1行:每行M個數,中間用空格隔開,對應格子中獎勵的價值。(1 <= A[i,j] <= 10000)
Output
輸出能夠獲得的最大價值。
Input示例
3 3 1 3 3 2 1 3 2 2 1
Output示例
17
解釋:https://blog.csdn.net/yuanjunlai141/article/details/51492590
/* 他們兩個走的步數是一致的,並且x+y=步數,可以根據這個進行降維 */ #include <iostream> #include <algorithm> #include <string.h> using namespace std; int dp[403][203][203],a[205][205]; int n,m; int main() { int i,j,k; while(cin>>m>>n) { for(i=1;i<=n;i++) for(j=1;j<=m;j++) cin>>a[i][j]; memset(dp,0,sizeof(dp)); for(k=2;k<=m+n;k++)//最多走m+n步,因為要從左上角走到右下角 { for(int x1=1;x1<=n && k-x1>=1;x1++) //k代表當前能從起點最多走多少步,所以x1 x2不能超過k-1 { for(int x2=1;x2<=n && k-x2>=1;x2++) { int d; if(x1!=x2) d=a[x1][k-x1]+a[x2][k-x2]; //數字不能重複取,所以要判斷是否相等 else d=a[x1][k-x1]; dp[k][x1][x2]=max(dp[k-1][x1-1][x2] , max(dp[k-1][x1][x2-1] , max(dp[k-1][x1-1][x2-1] , dp[k-1][x1][x2]))) + d; }//max中的4個dp陣列分別代表,(我們把兩個人分別命名為A B) A從左來,B從上來 A上B左 A左B左 A上B上 } } cout<<dp[m+n][n][n]<<endl; } return 0; }