方格取数+ 传纸条 noip2000 + noip2008 DP

Posted wondering-world

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了方格取数+ 传纸条 noip2000 + noip2008 DP相关的知识,希望对你有一定的参考价值。

方格取数

传纸条

 

两道题其实都差不多(DP方程都一样), 所以讲限制条件稍微多一点的传纸条。

 

首先,对题目进行翻译,我们完全可以把所谓来回,看做两次只能往右往下的完全不重复路线。

我们设 $f_{i,j,k,l}$ 表示第一次走到点 $(i , j)$ ,第二次走到点 $(k, l)$ 的最大和。

 

对于每一步有四种情况:

1.第一张纸条向下传,第二张纸条向下传;

2.第一张纸条向下传,第二张纸条向右传;

3.第一张纸条向右传,第二张纸条向下传;

4.第一张纸条向右传,第二张纸条向右传;

 

所以,我们就得到了状态转移方程

$f_{i,j,k,l}$ $=$ $max(f_{i-1,j,k-1,l} , f_{i-1,j,k,l-1}, f_{i,j-1,k-1,l}, f_{i,j-1,k,l-1}) + a_{i,j} + a_{k,l}$;

注意,在循环的时候,$l$应从 $j + 1$ 开始循环,只有这样才能确保两条线路不交叠,详情请手摸

(当然,如果您执意要从$1$开始,只需要在重复的时候判断并将状态减去$a_{i,j}$即可)

 

P1004 方格取数:

 

#include <bits/stdc++.h>
using namespace std;
#define N 10

inline int read(){
    int x = 0, s = 1;
    char c = getchar();
    while(!isdigit(c)){
        if(c == -)s = -1;
        c = getchar();
    }
    while(isdigit(c)){
        x = x * 10 + (c ^ 0);
        c = getchar();
    }
    return x * s;
}

int f[N][N][N][N];
int a[N][N];

inline int max_ele(int a, int b, int c, int d){
    int sum = a;
    if(b > sum) sum = b;
    if(c > sum) sum = c;
    if(d > sum) sum = d;
    return sum;
}

int main(){
    int n = read();
    memset(a, 0, sizeof(a));
    int x = 666, y = 666, w = 666;
    while(x && y && w){
        x = read(), y = read(), w = read();
        a[x][y] = w;
    }
    for(int i = 1;i <= n; i++)
        for(int j = 1;j <= n; j++)
            for(int k = 1;k <= n; k++)
                for(int l = 1;l <= n; l++){
                    f[i][j][k][l] = max_ele(f[i-1][j][k-1][l], f[i-1][j][k][l-1], f[i][j-1][k-1][l], f[i][j-1][k][l-1]) + a[i][j] + a[k][l];
                    if(i == k && l == j) f[i][j][k][l] -= a[i][j];
                }
    cout << f[n][n][n][n] << endl;
    return 0;                
}

 

 

 

 

P1006 传纸条:

 

 

#include <bits/stdc++.h>
using namespace std;
#define N 60

inline int read(){
    int x = 0, s = 1;
    char c = getchar();
    while(!isdigit(c)){
        if(c == -)s = -1;
        c = getchar();
    }
    while(isdigit(c)){
        x = x * 10 + (c ^ 0);
        c = getchar();
    }
    return x * s;
} 

int f[N][N][N][N];
int n, m;
int a[N][N];

inline int max_element(int a, int b, int c, int d){
    int sum = a;
    if(b > sum) sum = b;
    if(c > sum) sum = c;
    if(d > sum) sum = d;
    return sum;
}

int main(){
    n = read(), m = read();
    for(int i = 1;i <= n; i++)
        for(int j = 1;j <= m; j++)
            a[i][j] = read();
    for(int i = 1;i <= n; i++)
        for(int j = 1;j <= m; j++)
            for(int k = 1;k <= n; k++)
                for(int l = j + 1;l <= m;l++)
                    f[i][j][k][l] = max_element(f[i-1][j][k-1][l], f[i-1][j][k][l-1], f[i][j-1][k-1][l], f[i][j-1][k][l-1]) + a[i][j] + a[k][l];
    cout << f[n][m-1][n-1][m] << endl;        
    return 0;
}

 

 

 

 

 

以上是关于方格取数+ 传纸条 noip2000 + noip2008 DP的主要内容,如果未能解决你的问题,请参考以下文章

Luogu1006 传纸条 与 Luogu P2045方格取数加强版 (费用流)

动态规划数字三角形模型 AcWing 1027. 方格取数 275. 传纸条

动态规划数字三角形模型 AcWing 1027. 方格取数 275. 传纸条

动态规划数字三角形模型 AcWing 1027. 方格取数 275. 传纸条

NOIP 2000 方格取数 dp

codevs 2853 方格游戏--棋盘dp