1. 程式人生 > >方格取數(DP)

方格取數(DP)

兩個 urn ott 正整數 ane esp n) 題目 bit

描述

設有N*N的方格圖(N<=10,我們將其中的某些方格中填入正整數,而其他的方格中則放入數字0。如下圖所示(見樣例):

某人從圖的左上角的A 點出發,可以向下行走,也可以向右走,直到到達右下角的B點。在走過的路上,他可以取走方格中的數(取走後的方格中將變為數字0)。

此人從A點到B 點共走兩次,試找出2條這樣的路徑,使得取得的數之和為最大。

輸入

輸入的第一行為一個整數N(表示N*N的方格圖),接下來的每行有三個整數,前兩個表示位置,第三個數為該位置上所放的數。一行單獨的0表示輸入結束。

輸出

只需輸出一個整數,表示2條路徑上取得的最大的和。

樣例輸入

8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0

樣例輸出

67

題目分析:

dp[i][j][k]代表走i步第一條在j列,第二條在k列的最大和。

dp[i][j][k]=max{dp[i-1][j-1][k-1],dp[i-1][j-1][k],dp[i-1][j][k-1],dp[i-1][j][k]}+當前的第一個點和第二個點的值(若相同只加一次);

可以用滾動數組優化一下,這裏N很小,可以不考慮。

#include <bits/stdc++.h>
using namespace std;
int a[10][10];
int dp[20][10][10];
int f(int a,int b,int c,int d)
{
    
return max(max(max(a,b),c),d); } int main() { int n,x,y,z; scanf("%d",&n); while(~scanf("%d%d%d",&x,&y,&z),x||y||z) a[x][y]=z; for(int k=1;k<=2*n;k++)///走2*n步到達右下角 for(int i=1;i<=k;i++) for(int j=1;j<=k;j++) { dp[k][i][j]
=f(dp[k-1][i][j],dp[k-1][i-1][j],dp[k-1][i][j-1],dp[k-1][i-1][j-1]); if(i==j) dp[k][i][j]+=a[k-i][i];///相同 else dp[k][i][j]+=a[k-i][i]+a[k-j][j]; } printf("%d\n",dp[2*n][n][n]); }

方格取數(DP)