• codevs1169, 51nod1084(多线程dp)


    先说下codevs1169吧,

    题目链接: http://codevs.cn/problem/1169/

    题意: 中文题诶~

    思路: 多线程 dp

    用 dp[i][j][k][l] 存储一个人在 (i, j), 一个人在 (k, l) 位置时对答案的最大贡献, 那么动态转移方程式为:

    dp[i][j][k][l] = max(max(dp[i - 1][j][k - 1][l], dp[i - 1][j][k][l - 1]), max(dp[i][j - 1][k - 1][l], dp[i][j - 1][k][l - 1])) + a[i][j] + a[k][l]

    注意: 如果 (i, j) 和 (k, l) 相同的话只能 a[i][j], a[k][l] 只计算一个

    代码:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 const int MAXN = 51;
     5 int a[MAXN][MAXN], dp[MAXN][MAXN][MAXN][MAXN];
     6 
     7 int main(void){
     8     int n, m;
     9     cin >> n >> m;
    10     for(int i = 1; i <= n; i++){
    11         for(int j = 1; j <= m; j++){
    12             cin >> a[i][j];
    13         }
    14     }   
    15     for(int i = 1; i <= n; i++){
    16         for(int j = 1; j <= m; j++){
    17             for(int k = 1; k <= n; k++){
    18                 for(int l = 1; l <= m; l++){
    19                     dp[i][j][k][l] = max(max(dp[i - 1][j][k - 1][l], dp[i - 1][j][k][l - 1]), max(dp[i][j - 1][k - 1][l], dp[i][j - 1][k][l - 1]));
    20                     if(i != k || j != l) dp[i][j][k][l] += a[k][l];
    21                     dp[i][j][k][l] += a[i][j];
    22                 }
    23             }
    24         }
    25     }
    26     cout << dp[n][m][n][m] << endl;
    27     return 0;
    28 }
    View Code

    51nod10084

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1084

    这道题和上面那题差不多,不过数据范围更大,用四维 dp 的话无论时间复杂度还是空间复杂度都是不允许的

    可以发现,如果记录一下步数的话,可以根据步数和行数得出列数,那么也就和上面的差不多了

    用 dp[i][x1][x2] 记录第 i 步时第一个人走到第 x1 行, 第二个人走到第 x2 行时对答案的最大贡献

    那么动态转移方程式为:

    dp[i][x1][x2] = max(max(dp[i - 1][x1][x2], dp[i - 1][x1][x2 - 1]), max(dp[i - 1][x1 - 1][x2], dp[i - 1][x1 - 1][x2 - 1])) + a[x1][y1] + a[x2][y2]

    其中 y1 = i - x1, y2 = i - x2

    注意: (x1, y1) 和 (x2, y2) 相同时 a[x1][y1], a[x2][y2] 只能计算一个

    还有一个坑就是输入 n, m 的顺序是 m, n // 坑了我半天

    代码:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 const int MAXN = 2e2 + 10;
     5 int a[MAXN][MAXN], dp[MAXN << 1][MAXN][MAXN];
     6 
     7 int main(void){
     8     int n, m;
     9     cin >> m >> n;
    10     for(int i = 1; i <= n; i++){
    11         for(int j = 1; j <= m; j++){
    12             cin >> a[i][j];
    13         }
    14     }
    15     for(int i = 1; i <= n + m; i++){
    16         for(int x1 = 1; x1 <= min(n, i); x1++){
    17             int y1 = i - x1;
    18             for(int x2 = 1; x2 <= min(n, i); x2++){
    19                 int y2 = i - x2;
    20                 dp[i][x1][x2] = max(max(dp[i - 1][x1][x2], dp[i - 1][x1][x2 - 1]), max(dp[i - 1][x1 - 1][x2], dp[i - 1][x1 - 1][x2 - 1]));
    21                 if(x1 != x2 || y1 != y2) dp[i][x1][x2] += a[x2][y2];
    22                 dp[i][x1][x2] += a[x1][y1];
    23             }
    24         }
    25     }
    26     cout << dp[n + m][n][n] << endl;
    27     return 0;
    28 }
    View Code
  • 相关阅读:
    HAOI2018 简要题解
    HAOI2017 简要题解
    BZOJ 5477: 星际穿越
    HAOI2016 简要题解
    C#oracle还原imp实例
    oracle备份imp命令大全
    C#oracle备份和还原
    win10安装CAD后出现致命错误
    Oracle 恢复数据后,数据库中中文变成问号解决方法
    CAD 安装时出现.net frameword 3.5安装不上的问题
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7417863.html
Copyright © 2020-2023  润新知