• 1084. [SCOI2005]最大子矩阵【网格DP】


    Description

      这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵
    不能相互重叠。

    Input

      第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的
    分值的绝对值不超过32767)。

    Output

      只有一行为k个子矩阵分值之和最大为多少。

    Sample Input

    3 2 2
    1 -3
    2 3
    -2 3

    Sample Output

    9

    果然DP还是需要多练……
    f[i][j][p]保存当第i行为p状态时选了j个正方形的最大值
    p=1这一行只选左边
    p=2这一行只选右边
    p=3这一行选两个(但两个为独立的)
    p=4这一行选两个(两个并在一起)

     1 #include<iostream>
     2 #include<cstring> 
     3 using namespace std;
     4 
     5 int max5(int a,int b,int c,int d,int e)
     6 {
     7     return max(max(a,b),max(max(c,d),e));    
     8 } 
     9 int max3(int a,int b,int c)
    10 {
    11     return max(max(a,b),c);
    12 }
    13 int f[101][101][10],n,m,k,x,y,z;
    14 int main()
    15 {
    16     cin>>n>>m>>k;
    17     if (m==1)
    18     {
    19         for (int i=1;i<=n;++i)
    20         {
    21             cin>>x;
    22             for (int j=1;j<=k;++j)
    23             {
    24                 f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]);
    25                 f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][0])+x;
    26             }
    27         }
    28         cout<<max(f[n][k][0],f[n][k][1]);
    29     }
    30     else
    31     {
    32         memset(f,-0x3f,sizeof(f));
    33         for(int i=0;i<=n;i++)
    34             for(int j=0;j<=k;j++)
    35                 f[i][j][0]=0;
    36         for (int i=1;i<=n;++i)
    37         {
    38             cin>>x>>y;
    39             z=x+y;
    40             for (int j=1;j<=k;++j)
    41             {
    42                 f[i][j][0]=max5(f[i-1][j][0],f[i-1][j][1],f[i-1][j][2],f[i-1][j][3],f[i-1][j][4]);
    43                 f[i][j][1]=max5(f[i-1][j-1][0]+x,f[i-1][j][1]+x,f[i-1][j-1][2]+x,f[i-1][j][3]+x,f[i-1][j-1][4]+x);
    44                 f[i][j][2]=max5(f[i-1][j-1][0]+y,f[i-1][j-1][1]+y,f[i-1][j][2]+y,f[i-1][j][3]+y,f[i-1][j-1][4]+y);
    45                 f[i][j][3]=max3(f[i-1][j-1][1]+z,f[i-1][j-1][2]+z,f[i-1][j][3]+z);
    46                 if (j>=2)f[i][j][3]=max3(f[i][j][3],f[i-1][j-2][0]+z,f[i-1][j-2][4]+z);
    47                 f[i][j][4]=max5(f[i-1][j-1][0]+z,f[i-1][j-1][1]+z,f[i-1][j-1][2]+z,f[i-1][j-1][3]+z,f[i-1][j][4]+z);
    48                 
    49             }
    50         }
    51         cout<<max5(f[n][k][0],f[n][k][1],f[n][k][2],f[n][k][3],f[n][k][4]);
    52     }
    53 }
  • 相关阅读:
    【编程基础】const与#define的区别
    【Unity3D】模仿制作“神庙逃亡”吃金币后金币飞出屏幕效果
    【基础数学】素数判定、素数打表
    【NYOJ-187】快速查找素数—— 枚举法、筛选法、打表法
    【基础数学】质数,约数,分解质因数,GCD,LCM
    【NYOJ-35】表达式求值——简单栈练习
    【UVa-679】小球下落——二叉树的编号
    【UVa-442】矩阵链乘——简单栈练习
    【UVa-514】铁轨——栈的学习
    gitignore git提交忽略文件
  • 原文地址:https://www.cnblogs.com/refun/p/8678600.html
Copyright © 2020-2023  润新知