Squares access (checkerboard DP)

Title Description

With N \ times NN × N FIG squares (N \ le 9) (N≤9), wherein the grid we fill some positive integer, while the other is placed in the box 00 numbers. Shown (see examples) as shown below:

A
 0  0  0  0  0  0  0  0
 0  0 13  0  0  6  0  0
 0  0  0  0  7  0  0  0
 0  0  0 14  0  0  0  0
 0 21  0  0  0  4  0  0
 0  0 15  0  0  0  0  0
 0 14  0  0  0  0  0  0
 0  0  0  0  0  0  0  0
                         B

Someone from AA point of view of the upper left corner, you can walk down, you can also go to the right until you reach the bottom right corner of the BB point. On the way through, he can take away the number of squares (square will be removed after the figures become 00).
This person go from point to point BB AA total of two, try to find such a path 22, so that the number of acquired and maximum.

Input Format

A first act input integer NN (represented by N \ times NN × N FIG squares), each line has three next integer, indicates the position of the first two, are placed on the number of positions for the third number. A separate line 00 indicates the end of input.

Output Format

Only output an integer representing the path 22 to obtain the maximum and.

Sample input and output

Input # 1

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

Output # 1

67

Ideas:

With code: 

  1. Can only downward, or right away, therefore, equal to the number of steps to go plus abscissa ordinate
  2. And a known number of steps to go to confirm the size of the abscissa of a point
  3. Known number of steps, there must be two paths consisting of two coordinates (two coordinates may be the same) 
  4. Thus obtained may be recursive formula: dp [k] [i] [j] = max (max (dp [k-1] [i] [j], dp [k-1] [i] [j-1]) , max (dp [k-1] [i-1] [j], dp [k-1] [i-1] [j-1])) + a [i] [ki] + a [j] [ kj];         
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
	int a[30][30]= {0},n,x,y,num,dp[30][30][30]= {0};
	cin>>n;
	do {
		cin>>x>>y>>num;
		a[x][y]=num;
	} while(x||y);   //输入
	for(int k=2; k<=n+n; k++) { //步数最大为n+n
		for(int i=n; i&&(k-i<=n); i--) { //k-i>n时,纵坐标会超出方格大小
			for(int j=n; j>=i&&(k-j<=n); j--) {	//j>=i :相对右边的坐标
				dp[k][i][j]=max(max(dp[k-1][i][j],dp[k-1][i][j-1]),max(dp[k-1][i-1][j],dp[k-1][i-1][j-1]));
				dp[k][i][j]+=a[i][k-i];
				if(i!=j)dp[k][i][j]+=a[j][k-j];  //如果两条路径终点不相同
			}
		}
	}
	cout<<dp[n+n][n][n]<<endl;
	return 0;
}

 

Published 42 original articles · won praise 16 · views 3404

Guess you like

Origin blog.csdn.net/qq_41542638/article/details/99015163