hiho 1617 - 方格取數 - dp
阿新 • • 發佈:2017-10-29
包含 ring width ++ 多少 png es2017 alt 不能
題目鏈接
描述
給定一個NxN的方格矩陣,每個格子中都有一個整數Aij。小Hi和小Ho各自選擇一條從左上角格子到右下角格子的路徑,要求路徑中每一步只能向右或向下移動,並且兩條路徑不能相交(除了左上右下起止方格)。
現在將兩條路徑經過的整數加起來求和。你能計算出這個和最大是多少嗎?
輸入
第一行包含一個整數N。
以下N行每行包含N個整數,代表方格矩陣中的數字。
對於50%的數據,1 ≤ N ≤ 50
對於100%的數據,1 ≤ N ≤ 200 1 ≤ Aij ≤ 100
---------------------------------------------------------------------------------------------------------------------------------------------
如下圖那樣一行行的處理
dp[row][i][j]代表 第row行選取第i和第j個元素時的最大值,
dp[row][i][j]最多只和上一行的四個元素相關,註意上三角和下三角這四個元素的索引方式不同。
因為第row行只和第row-1行相關,所以只需保存前一行的結果。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 256; int dp[N][N][2]; int A[N][N];int n; int get(int row,int i){ if(row<=n+1){ if(i>=row) return 0; return A[row-i][i]; } else{ int x = row-n-1+i; if(x>n) return 0; return A[row-x][x]; } } int main(){ cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&A[i][j]); memset(dp,0,sizeof(dp)); dp[1][1][0] = A[1][1]*2; int cur = 1; for(int row=3;row<n*2;row++){ int cnt = (row>n+1)?(n*2-row+1+1):(row); int gap = (row>n+1)? 1: -1; for(int i=1;i<cnt;i++) for(int j=i+1;j<cnt;j++){ int max1 = std::max(dp[i][j][!cur],dp[i+gap][j][!cur]); int max2 = std::max(dp[i][j+gap][!cur],dp[i+gap][j+gap][!cur]); dp[i][j][cur] = std::max(max1,max2)+get(row,i)+get(row,j); } cur = cur?0:1; } printf("%d\n",dp[1][2][!cur]+A[n][n]*2); return 0; }
hiho 1617 - 方格取數 - dp