方格取数方格取数方格取数
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
题目大意:
有两个士兵,从1,1走到n,n路上有许多money,但他们只能往下或往右走,他们最多能得到多少money
解题方法:
用四位数组表示两个士兵的位置,详情请见动态转移方程:
动态转移方程:
f[i][j][i1][j1]=max{l+a[i][j](i==i1)and(j==j1)l+a[i][j]+a[i1][j1]elsef[i][j][i1][j1]=max\left\{\begin{matrix}l+a[i][j]&(i==i1)and(j==j1)\\ l+a[i][j]+a[i1][j1]&else\end{matrix}\right.f[i][j][i1][j1]=max{l+a[i][j]l+a[i][j]+a[i1][j1](i==i1)and(j==j1)else
标注:
ij分别为第一个士兵的行列,i1j1分别为第二个士兵的行列,l为上一步最大的,第一行是因为重复了,金币只能拿一份,第二行是两个士兵那两份
#include<cstdio>
#include<iostream>
using namespace std;
int n,x,y,d,a[12][12],f[12][12][12][12];
int main()
{scanf("%d%d%d%d",&n,&x,&y,&d);while (!((x==0)&&(y==0)&&(d==0))){a[x][y]=d;scanf("%d%d%d",&x,&y,&d);}for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)for (int i1=1;i1<=n;i1++)for (int j1=1;j1<=n;j1++){x=max(f[i-1][j][i1-1][j1],f[i][j-1][i1][j1-1]);y=max(f[i-1][j][i1][j1-1],f[i][j-1][i1-1][j1]);if ((i==i1)&&(j==j1)) f[i][j][i1][j1]=max(x,y)+a[i][j];else f[i][j][i1][j1]=max(x,y)+a[i][j]+a[i1][j1];}printf("%d",f[n][n][n][n]);
}
提示:
本体的相似题:传纸条(ssl 1589)因太相似就不写了