• 1084 矩阵取数问题 V2


    基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
    一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上。第1遍时只能向下和向右走,第2遍时只能向上和向左走。两次如果经过同一个格子,则该格子的奖励只计算一次,求能够获得的最大价值。
     
    例如:3 * 3的方格。
     
    1 3 3
    2 1 3
    2 2 1
     
    能够获得的最大价值为:17。1 -> 3 -> 3 -> 3 -> 1 -> 2 -> 2 -> 2 -> 1。其中起点和终点的奖励只计算1次。
     
    Input
    第1行:2个数M N,中间用空格分隔,为矩阵的大小。(2 <= M, N <= 200)
    第2 - N + 1行:每行M个数,中间用空格隔开,对应格子中奖励的价值。(1 <= A[i,j] <= 10000)
    Output
    输出能够获得的最大价值。
    Input示例
    3 3
    1 3 3
    2 1 3
    2 2 1
    Output示例
    17



    // 读数真是会玩, 首先说是 M * N 的矩阵,然后读入是 m, n ,然而,却是 n 行 m 列
    //其实仔细分析一下这个问题可知,就是从起点走两条线向终点,然后可以想到,其实两段线并不会相交,因为如果相交,必定存在一个不相交的方案使和更大。
    dp[st][a][b] 表示,走 st 步,第一条线在 a 行, 第二条线在 b 行,各自的列数可以计算出,然后就分四种情况愉快的dp辣
    DP:
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define MOD 998244353
     4 #define INF 0x3f3f3f3f
     5 #define LL long long
     6 #define MX 205
     7 
     8 int m, n;
     9 int dat[MX][MX];
    10 int dp[MX*2][MX][MX]; //step , a , b
    11 
    12 int main()
    13 {
    14     while (scanf("%d%d",&m,&n)!=EOF)
    15     {
    16         for (int i=1;i<=n;i++)
    17         {
    18             for (int j=1;j<=m;j++)
    19                 scanf("%d",&dat[i][j]);
    20         }
    21         int ut = n+m-2;
    22         for (int st=ut;st>=0;st--)
    23         {
    24             for (int a=1;a<=n;a++)
    25             {
    26                 for (int b=1;b<=a;b++)
    27                 {
    28                     int ay = st-a+2;
    29                     int by = st-b+2;
    30                     if (ay<1||ay>n||by<1||by>n) continue;
    31 
    32                     int tp1 = max(dp[st+1][a+1][b+1],dp[st+1][a][b]);
    33                     int tp2 = max(dp[st+1][a+1][b], dp[st+1][a][b+1]);
    34                     tp1 = max(tp1,tp2);
    35                     if (a==b)
    36                         dp[st][a][b] = max(dp[st][a][b],tp1 + dat[a][ay]);
    37                     else
    38                         dp[st][a][b] = max(dp[st][a][b],tp1 + dat[a][ay] + dat[b][by]);
    39                     //printf("?:%d %d %d %d
    ",st,a,b,dp[st][a][b]);
    40                 }
    41             }
    42         }
    43         printf("%d
    ",dp[0][1][1]);
    44     }
    45     return 0;
    46 }
    View Code
    最小费用最大流也可做,正好学习一下


     
  • 相关阅读:
    MFC Picture Ctrl 无失真自适应显示图片
    肖申克的救赎
    iOS开发常用工具
    代码管理工具 --- git的学习笔记四《重新整理git(1)》
    压缩与解压缩
    读书笔记——金融学-投资哪些事(职业投资人),读报
    读书笔记——金融学-《国富论》
    文件下载 NSURLConnection——文件下载与上传
    视频播放一
    XML解析
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7763960.html
Copyright © 2020-2023  润新知