AcWing 1027. Grid access [DP dynamic programming] C++ version problem solution

topic

There is an N×N grid. We fill in some of the squares with positive integers, and the other squares with the number 0. As shown below:

Insert picture description here

Someone starts from A in the upper left corner of the figure, and can walk down or to the right until he reaches point B in the lower right corner.

On the way he walks, he can take the number in the square (the square after taking it will become the number 0).

This person has walked twice from point A to point B. Try to find two such paths so that the sum of the numbers obtained is the largest.

Input format The
first line is an integer N, representing an N×N grid graph.

Each subsequent row has three integers, the first is the row number, the second is the column number, and the third is the number placed on the row and column.

Row and column numbers start from 1.

A line of "0 0 0" means the end.

Output format
Output an integer that represents the largest sum obtained on the two paths.

Data range
N≤10
Input example:
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 example:
67

Ideas

Go only once:
f[i,j] representation from all (1,1) went to (i,j)a maximum of paths f[i,j]= max(f[i-1,j]+ w[i], f[i-1][j]+ w[i])
to go twice:
f[i1,j1,i2,j2 ] represents all from (1,1),(1,1)approaching the (i1,j1),(i2,j2)maximum path
? How to deal with "the same - a grid that can not be repeated select"
Only i1 + j1 == i2 +j2when the two It is possible
f[k, i1, i2]that the grids of the paths overlap, which means that the maximum value of all the paths that have been traveled (1,1),(1,1)separately, and (i1,k-i1), (i2,k-i2)that the sum of
kthe horizontal and vertical coordinates of the grids where the two routes are currently going.
k = i1 + j1 = i2+ j2

Thus the state of f[i1][j1][i2][j2]optimization into a three dimensional f[k][i1][i2]
equivalent to the [i1][k−i1][i2]k−i2]
Insert picture description here
state transition Solving equation:
Consider four kinds moves:

Article 1: Next Article 2: Next

f[i1-1]][j1][i2-1][j2]==f[k-1][i1-1][i2-1];

Article 1: Under Article 2: Right

f[i1-1][j1][i2][j2-1]==f[k-1][i1-1][i2];

Article 1: Right Article 2: Down

f[i1][j1-1][i2-1][j2]==f[k-1][i1][i2-1];

Article 1: Right Article 2: Right

f[i1][j1-1][i2][j2-1]==f[k-1][i1][i2];
Insert picture description here

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=15;
int w[N][N];
int f[N*2][N][N];
int main()
{
    
    
    int n;
    cin>>n;
    int a,b,c;
    while(cin>>a>>b>>c,a||b||c) w[a][b]=c;
    for(int k=2;k<=n*2;k++)
      for(int i1=1;i1<=n;i1++)
       for(int i2=1;i2<=n;i2++)
         {
    
    
             int j1=k-i1,j2=k-i2;
             int t=w[i1][j1];
             if(i1!=i2)  t+=w[i2][j2];        //未走到同一格子
             if(i1>=1&&i1<=n&&i2>=1&&i2<=n)   //判断是否在边界内
             {
    
    
                int &x=f[k][i1][i2];
                x=max(x,f[k-1][i1-1][i2-1]+t);
                x=max(x,f[k-1][i1-1][i2]+t);
                x=max(x,f[k-1][i1][i2-1]+t);
                x=max(x,f[k-1][i1][i2]+t);
             }
         }
    cout<<f[n*2][n][n]<<endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45629285/article/details/110006371