4777: 方格取数 动态规划

发布时间 2023-03-27 13:43:40作者: CRt0729

描述

 

 

设有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
 

一个四重循环枚举两条路分别走到的位置。由于每个点均从上或左继承而来,故内部有四个if,分别表示两个点从上上、上左、左上、左左继承来时,加上当前两个点所取得的最大值。

a[i][j]表示(i,j)格上的值,sum[i][j][h][k]表示第一条路走到(i,j),第二条路走到(h,k)时的最优解。

例如,sum[i][j][h][k] = max{sum[i][j][h][k], sum[i-1][j][h-1][k] + a[i][j] + a[h][k]},表示两点均从上面位置走来。

当(i,j) != (h,k))时 sum[i][j][h][k]:=max{sum[i-1][j][h-1][k],sum[i][j-1][h][k-1],sum[i-1][j][h][k-1],sum[i][j-1][h-1][k]}+a[i][j]+a[h][k];

当(i,j) = (h,k)时 sum[i][j][h][k]:=max{sum[i-1][j][h-1][k],sum[i][j-1][h][k-1],sum[i-1][j][h][k-1],sum[i][j-1][h-1][k]}+a[i][j];

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int f[11][11][11][11],a[11][11];
 4 int n,x,y,z;
 5 int main()
 6 {
 7     cin>>n;
 8     while(cin>>x>>y>>z)
 9     {
10         if(!x&&!y&&!z)break;
11         a[x][y] = z;
12     }
13     for(int i=1;i<=n;i++)
14         for(int j=1;j<=n;j++)
15             for(int h=1;h<=n;h++)
16                 for(int l=1;l<=n;l++)
17                 {
18                     int t1 = max(f[i-1][j][h-1][l],f[i][j-1][h][l-1]);
19                     int t2 = max(f[i-1][j][h][l-1],f[i][j-1][h-1][l]);
20                     f[i][j][h][l] = max(t1,t2)+a[i][j]; //计算两条路线分别到达(i,j)和(h,l)时的最优值 
21                     if(i!=h && j!=l)f[i][j][h][l]+=a[h][l]; //如果两条路线的点不相同,那还需要把(h,j)到达的点数值加起来 
22                 }
23     cout<<f[n][n][n][n];
24      return 0;
25 }