1. 程式人生 > >【DP】ssl 1010 方格取數(多執行緒DP)

【DP】ssl 1010 方格取數(多執行緒DP)

Description

設有N*N的方格圖(N<=10,我們將其中的某些方格中填入正整數,而其他的方格中則放入數字0。如下圖所示(見樣例):
在這裡插入圖片描述
  某人從圖的左上角的A 點出發,可以向下行走,也可以向右走,直到到達右下角的B點。在走過的路上,他可以取走方格中的數(取走後的方格中將變為數字0)。
  此人從A點到B 點共走兩次,試找出2條這樣的路徑,使得取得的數之和為最大。

Input

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

Output

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

Sample Input

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

Sample Output

67

思路

兩次路徑同時走,用一個四維陣列來儲存兩條路徑可以獲得的最大值。
動態轉移方程太長,不好寫,還是直接看程式碼講吧。

程式碼

#include<iostream>
#include<cstdio>
using namespace std;
int n,x,y,z,a[11][11],f[11][11][11][11];
int main()
{
	scanf
("%d",&n); scanf("%d%d%d",&x,&y,&z); while (x!=0&&y!=0&&z!=0) { a[x][y]=z; scanf("%d%d%d",&x,&y,&z); }//讀入每一個有權值的位置 for (int i=1;i<=n;i++) for (int j=1;j<=n;j++)//i,j表示第一條路徑走到的位置 for (int x=1;x<=n;x++) for (int y=1;y<=n;y++)//x,y表示第二條路徑走到的位置
{ f[i][j][x][y]=max(max(f[i-1][j][x-1][y],f[i-1][j][x][y-1]),max(f[i][j-1][x][y-1],f[i][j-1][x-1][y]))+a[i][j]+a[x][y];//在兩條路徑的不同走法中找到一個最大的並加上兩條路徑的當前位置的權值存在當前位置裡。 if (i==x&&j==y)//兩條路徑走到一個點時,只需要計一次權值。 f[i][j][x][y]-=a[i][j]; } printf("%d",f[n][n][n][n]); }

ssl題庫的樣例輸入有問題,要輸入用部落格裡的就可以了。