第九章 動態規劃-1277:【例9.21】方格取數

1277:【例9.21】方格取數

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2603 通過數: 1824
【題目描述】
設有N×N的方格圖,我們在其中的某些方格中填入正整數,而其它的方格中則放入數字0。如下圖所示:

在這裏插入圖片描述

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

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

【輸入】
第一行爲一個整數N(N≤10),表示N×N的方格圖。

接下來的每行有三個整數,第一個爲行號數,第二個爲列號數,第三個爲在該行、該列上所放的數。一行“0 0 0”表示結束。

【輸出】
第一個整數,表示兩條路徑上取得的最大的和。

【輸入樣例】
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


思路:從A到B走兩次 等同於兩點同時從A到B 只要路徑不重合即可

dp[i][j][k][l]表示第一個點座標爲(i,j)第二個點座標爲(k,l)時的取數之和
在這裏插入圖片描述
. 設狀態:f[i][j][k][l];//表示兩條路同時走,第一條路徑走到(i,j)時,第二條走到(k,l)時的最大數字和;

  1. 初始狀態:f[0][0][0][0]=0;

    最終狀態:f[n][n][n][n];

  2. 狀態轉移方程:當i == k && j == l時,f[i][j][k][l]=max{f[i-1][j][k-1][l],f[i][j-1][k][l-1],f[i-1][j][k][l-1],f[i][j-1][k-1][l])+a[i][j];//取上上,左左,上左,左上四個方向的最大值加上當前的值;

當i!=k&&j!=l時,f[i][j][k][l]=max{f[i-1][j][k-1][l],f[i][j-1][k][l-1],f[i-1][j][k][l-1],f[i][j-1][k-1][l])+a[i][j]+a[k][l];//取上上,左左,上左,左上四個方向的最大值加上兩條路徑當前的值;

#include<cstdio>
#include<iostream>
#define N  11
using namespace std;
int f[N][N][N][N],a[N][N];
int n, x, y, z;
int max1, max2;
int main(){
	cin >> n;
	while(scanf("%d%d%d",&x,&y,&z) ==3 && x && y && z)//輸出000結束
	{
		a[x][y] = z; //賦值
	}
	for(int i = 1; i <= n; i++)
	 {
	 	for(int j = 1; j <= n; j++)
         {
         	for(int k = 1; k <=n; k++)
         	{
         		for(int l = 1; l <= n;l++)
         		{
         			max1 = max(f[i-1][j][k-1][l],f[i][j-1][k][l-1]);
         			max2 = max(f[i-1][j][k][l-1],f[i][j-1][k-1][l]);
         			f[i][j][k][l] = max(max1,max2) + a[i][j];
         			if(i != k && j != l)
         			f[i][j][k][l] += a[k][l];
				 }
			 }
		 }
	 }
	printf("%d",f[n][n][n][n]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章