zoukankan      html  css  js  c++  java
  • CH5103 传纸条【线性dp】

    5103 传纸条 0x50「动态规划」例题

    描述

    给定一个 N*M 的矩阵A,每个格子中有一个整数。现在需要找到两条从左上角 (1,1) 到右下角 (N,M) 的路径,路径上的每一步只能向右或向下走。路径经过的格子中的数会被取走。两条路径不能经过同一个格子。求取得的数之和最大是多少。N,M≤50。

    输入格式

    第一行有2个用空格隔开的整数n和m,表示有n行m列(1<=n,m<=50)。
    接下来的n行是一个n*m的矩阵,每行的n个整数之间用空格隔开。

    输出格式

    一个整数,表示答案。

    样例输入

    3 3
    0 3 9
    2 8 5
    5 7 0

    样例输出

    34

    数据范围与约定

    • 30%的数据满足:1<=m,n<=10 
      100%的数据满足:1<=m,n<=50

    来源

    CCF NOIP2008 T3

    题意:n*m的格子里每个格子有一个权值,从(1,1)走到(n,m)两条路,(只能向下或者向右)求路径之和。走过的格子只算一次权值。

    思路:

    把“路径长度”即当前走过的步数作为DP的“阶段”。【因为只能向下或向右,走到(n,m)时的路径长度是n+m-2】

    每一个阶段中,把两条路径同时扩展一步,路径长度增加1,从而转移到下一个阶段。

    还需确定两条路径当前的末尾位置。并且 x1+y1 = x2 + y2 = i + 2

    所以就可以用三维dp维护,每次有4种扩展方式。并且要考虑扩展后是否两个点坐标相同。

    目标是dp[n+m-2][n][n]

     1 #include <bits/stdc++.h>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<stdio.h>
     6 #include<cstring>
     7 #include<map>
     8 
     9 #define inf 0x3f3f3f3f
    10 using namespace std;
    11 typedef long long LL;
    12 
    13 int n, m;
    14 const int maxn = 55;
    15 int g[maxn][maxn];
    16 int dp[maxn * 2][maxn][maxn] = {0};
    17 
    18 int main()
    19 {
    20     scanf("%d%d", &n, &m);
    21     for(int i = 1; i <= n; i++){
    22         for(int j = 1; j <= m; j++){
    23             scanf("%d", &g[i][j]);
    24         }
    25     }
    26 
    27     dp[0][1][1] = g[1][1];
    28     for(int i = 0; i <= n + m - 2; i++){
    29         for(int x1 = 1; x1 <= min(n, i + 1); x1++){
    30             for(int x2 = 1; x2 <= min(n, i + 1); x2++){
    31                 int y1 = i + 2 - x1, y2 = i + 2 - x2;
    32                 if(x1 == x2 && y1 == y2){
    33                     dp[i + 1][x1][x2] = max(dp[i + 1][x1][x2], dp[i][x1][x2] + g[x1][y1 + 1]);
    34                     dp[i + 1][x1 + 1][x2 + 1] = max(dp[i + 1][x1 + 1][x2 + 1], dp[i][x1][x2] + g[x1 + 1][y1]);
    35                 }
    36                 else{
    37                     dp[i + 1][x1][x2] = max(dp[i + 1][x1][x2], dp[i][x1][x2] + g[x1][y1 + 1] + g[x2][y2 + 1]);
    38                     dp[i + 1][x1 + 1][x2 + 1] = max(dp[i + 1][x1 + 1][x2 + 1], dp[i][x1][x2] + g[x1 + 1][y1] + g[x2 + 1][y2]);
    39                 }
    40 
    41                 if(x1 == x2 + 1 && y1 + 1 == y2){
    42                     dp[i + 1][x1][x2 + 1] = max(dp[i + 1][x1][x2 + 1], dp[i][x1][x2] + g[x1][y1 + 1]);
    43                 }
    44                 else{
    45                     dp[i + 1][x1][x2 + 1] = max(dp[i + 1][x1][x2 + 1], dp[i][x1][x2] + g[x1][y1 + 1] + g[x2 + 1][y2]);
    46                 }
    47 
    48                 if(x1 + 1 == x2 && y1 == y2 + 1){
    49                     dp[i + 1][x1 + 1][x2] = max(dp[i + 1][x1 + 1][x2], dp[i][x1][x2] + g[x1 + 1][y1]);
    50                 }
    51                 else{
    52                     dp[i + 1][x1 + 1][x2] = max(dp[i + 1][x1 + 1][x2], dp[i][x1][x2] + g[x1 + 1][y1] + g[x2][y2 + 1]);
    53                 }
    54             }
    55         }
    56     }
    57     printf("%d
    ", dp[n + m - 2][n][n]);
    58     return 0;
    59 }
  • 相关阅读:
    疫苗玻璃瓶行业,能发生国产替代吗
    马斯克是如何借力打力的?
    什么是分析立体主义
    这5家公司代表了高瓴资本眼中的科技产业未来
    玻尿酸之王华熙生物,为什么要做食品和饮料(下)
    ajax缺点
    babel转码器
    docker 缺陷
    MVVM中的vm双向监听和mvc的缺点
    mybatisPlus中的模糊查询问题
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9744977.html
Copyright © 2011-2022 走看看