My DP training program: three takes the number of panels

Questions surface:

background

JerryZhou students often adapt the exercises to make their own.

That day, he adapted a question. . . . .

description

N * N has the checkered, some of which will be filled squares positive integer,
while the other box placed 0.

Get someone from the top left corner of map, you can go down, you can also go to the right until you reach the bottom right corner.

On the way through, he took away the number of squares. (After removal of the digital box to 0)
the person away from the upper left to lower right corner of a total of three times, try to find the three paths, so that the sum of the maximum number achieved.

format

Input Format

The first line: N (4 <= N < = 20)
Next, a N * N matrix, each element of the matrix is not more than 80, not less than 0

Output Format

A line representing the maximum sum.

 

 

Listen ... I heard a kind of classic DP ...

Anyway, I do not ...

I started thinking very single-minded: take the time to do press, then repeat three times

Then, and then listen to the sound of a WA ...

Anyway, finally thought out solution to a problem is the idea of ​​watching ... ooo, ooo I was too dishes

 

There is a more important conclusion:

  In the matrix, if we can only go down or go right, then, to know the premise of origin, the number of steps, the number of rows, columns, know where the two can push the third .

  And, come to the same place two points, will spend the same number of steps .

 

These conclusions support from our ideas: let go three points at the same time .

Construction try following state: f [x] [i] [j] [k], representative of steps walked x, i, j, k are representative of three walked i-th row, j-th, k-th row.

In fact, it is equivalent to the i-th row come to x-i + 2 row j th row x-j + 2 columns k-th row of the x-k + 2 columns.

 For each state, there will be up to the state before the 8 states (each point respectively from the left and come from the top), that is, from the eight states selected one of the best state to update the current status.

Equation is written as:

F [X, I, J, K] = max (F [X- . 1 , I- . 1 , J, K], F [X- . 1 , I, J- . 1 , K], F [X- . 1 , I , J, - K- . 1 ], wherein one of the upper // 
          F [X- . 1 , I- . 1 , J- . 1 , K], F [X- . 1 , I- . 1 , J, - K- . 1 ], F [X- . 1 , I, J- . 1 , - K- . 1 ], from the top to two // where
          F [X- . 1 , I- . 1 , J- . 1 , - K- . 1 ], // all three from the top to
          F [X- . 1 , I, J, K]) // not from the top to three
          + add // value a / two / three points corresponding to the need to add

 

(No special code boundary is judged invalid because previous state corresponding f is 0, that is, if there is a legitimate state on any bigger than it)

Due to the number of the grid is removed gone, so there is no judgment in any two / three points went to the same square, you do not want to add up. (I'll be there ... silly three positions are pairwise disjoint:! I = j && j = k = k && i!! , Me as i = j && j = k on the line ...!!)

 

 

code show as below:

#include <cstdio>
#include <cstdlib>
int N;
int v[21][21];
int f[41][21][21][21];
int max(int a,int b){return a>b?a:b;}
void dp(){
    for(int x=1;x<=2*N-2;x++){
        for(int i=1;i<=x+1&&i<=N;i++){
            for(int j=1;j<=x+1&&j<=N;j++){
                for(int k=1;k<=x+1&&k<=N;k++){
                    int add;
                    if(i==j&&j==k)add=v[i][x-i+2];
                    if(i==j&&j!=k)add=v[i][x-i+2]+v[k][x-k+2];
                    if(i!=j&&j==k)add=v[i][x-i+2]+v[j][x-j+2];
                    if(i==k&&j!=k)add=v[i][x-i+2]+v[j][x-j+2];
                    if(i!=j&&j!=k&&i!=k)add=v[i][x-i+2]+v[j][x-j+2]+v[k][x-k+2];
                    f[x][i][j][k]=max(f[x-1][i-1][j][k],max(f[x-1][i][j-1][k],max(f[x-1][i][j][k-1],
                    max(f[x-1][i-1][j-1][k],max(f[x-1][i-1][j][k-1],max(f[x-1][i][j-1][k-1]
                    ,max(f[x-1][i-1][j-1][k-1],f[x-1][i][j][k])))))))+add;
                }
            }
        }
    }
}
int main () {
    scanf("%d",&N);
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++)
            scanf("%d",&v[i][j]);
    }
    f[0][1][1][1]=v[1][1];
    dp();
    printf("%d",f[2*N-2][N][N][N]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Zarax/p/12041655.html