• P1006 传纸条


    链接

    刚开始想的是两次01背包,把第一次走过的给记录下来。好像不太好记录,

    参考了大佬的博客,数据范围不是很大,四维数组就可以了,

    a,b第一个人走的,c,d代表第二个人

    dp[a][b][c][d] = max{dp[a][b -1][c][d -1] , dp[a - 1][b][c -1][d],

                                 dp[a][b -1][c -1][d],dp[a - 1][b][c][d -1]}+a[a][b] + a[c][d];

     只要保证纵坐标不一样就行,d = b + 1开始循环

    最后输出是dp[n][m - 1][n - 1][m];

    第一个人到第二个人只能往右或者往下走,所以到达的点是n,m-1

    同理,第二个人到达的点是n-1,m;

    如果卡的厉害,可以变为三维数组,怎么操作呢?

    每次转移的时候,两个人走的步数是相等的,

    枚举横坐标

    k表示总的步数,

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 int a[55][55],dp[110][55][55];
     5 int n,m;
     6 
     7 int main(){
     8     //freopen("in","r",stdin);
     9     ios::sync_with_stdio(0);
    10     cin >> n >> m;
    11     for(int i = 1; i <= n; i++){
    12         for(int j = 1; j <= m; j++){
    13             cin >> a[i][j];
    14         }
    15     }
    16     for(int k = 1; k <= n + m - 1; k++){
    17         for(int i = 1; i <= n; i++){
    18             for(int j = 1; j <= n; j++){
    19                 if(k - i < 0 || k - j < 0)
    20                     continue;
    21                 dp[k][i][j] = max(max(dp[k - 1][i][j],dp[k - 1][i - 1][j - 1]),max(dp[k - 1][i][j - 1],dp[k - 1][i - 1][j])) + a[i][k - i + 1] + a[j][k - j + 1];
    22                 if(i == j)
    23                     dp[k][i][j] -=  a[i][k - i + 1];
    24             }
    25         }
    26     }
    27     cout << dp[n + m - 1][n][n] << endl;
    28     return 0;
    29 }
    View Code
  • 相关阅读:
    Ubuntu下下载Android源码
    升级Android 3.1ADT 和SDK
    ubuntu10.04手动安装jdk1.6.0_24配置
    安装VM Tools
    Singleton (单件模式)
    biztalk2004安装时应该注意的几点
    欢迎高手加入.NET技术群
    Observer(观察者模式)
    无眠
    A⑤权限管理分配权限:提交的是节点的id列表
  • 原文地址:https://www.cnblogs.com/xcfxcf/p/12774167.html
Copyright © 2020-2023  润新知