• BZOJ1084 [SCOI2005] 最大子矩阵


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1084

    Description

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

    Input

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

    Output

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

    在一次AC背后是不知多少次的WA……真是呵呵

    dp[i][j][k]表示到第i行,取了j个,k表示这一行的状态:0为上下都不取,1为去上面,2为取下面,3为上下都取且不相连,4为上下都取且相连

    然后同样的状态在两行视为连在一起不能拆开,第一次推错了,好歹说一说嘛。

    然后数组大小开到刚刚好101就WA,开到110就AC,算我作死。

    然后状态转移方程有好多好多道,看代码吧。

    然后就没有然后了。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #define rep(i,l,r) for(int i=l; i<=r; i++)
     6 #define clr(x,y) memset(x,y,sizeof(x))
     7 using namespace std;
     8 const int INF = 0x3fffffff;
     9 int n,m,k,ans=-INF,num[110][3],dp[110][20][5];
    10 inline int read(){
    11     int ans = 0, f = 1;
    12     char c = getchar();
    13     while (!isdigit(c)){
    14         if (c == '-') f = -1;
    15         c = getchar();
    16     }
    17     while (isdigit(c)){
    18         ans = ans * 10 + c - '0';
    19         c = getchar();
    20     }
    21     return ans * f;
    22 }
    23 int main(){
    24     n = read(); m = read(); k = read();
    25     rep(i,1,n) rep(j,1,m) num[i][j] = read();
    26     rep(i,0,n) rep(j,0,k) rep(l,0,4) dp[i][j][l] = -INF;
    27     dp[0][0][0] = 0;
    28     rep(i,0,n-1) rep(j,0,k){
    29         if (m == 1){
    30             rep(l,0,1) dp[i+1][j][0] = max(dp[i+1][j][0],dp[i][j][l]);
    31             dp[i+1][j][1] = max(dp[i+1][j][1],dp[i][j][1] + num[i+1][1]);
    32             dp[i+1][j+1][1] = max(dp[i+1][j+1][1],dp[i][j][0] + num[i+1][1]);
    33         }
    34         else{
    35             rep(l,0,4) dp[i+1][j][0] = max(dp[i+1][j][0],dp[i][j][l]);
    36             dp[i+1][j][1] = max(dp[i+1][j][1],dp[i][j][1] + num[i+1][1]);
    37             dp[i+1][j][1] = max(dp[i+1][j][1],dp[i][j][3] + num[i+1][1]);
    38             dp[i+1][j+1][1] = max(dp[i+1][j+1][1],dp[i][j][0] + num[i+1][1]);
    39             dp[i+1][j+1][1] = max(dp[i+1][j+1][1],dp[i][j][2] + num[i+1][1]);
    40             dp[i+1][j+1][1] = max(dp[i+1][j+1][1],dp[i][j][4] + num[i+1][1]);
    41             dp[i+1][j][2] = max(dp[i+1][j][2],dp[i][j][2] + num[i+1][2]);
    42             dp[i+1][j][2] = max(dp[i+1][j][2],dp[i][j][3] + num[i+1][2]);
    43             dp[i+1][j+1][2] = max(dp[i+1][j+1][2],dp[i][j][0] + num[i+1][2]);
    44             dp[i+1][j+1][2] = max(dp[i+1][j+1][2],dp[i][j][1] + num[i+1][2]);
    45             dp[i+1][j+1][2] = max(dp[i+1][j+1][2],dp[i][j][4] + num[i+1][2]);
    46             dp[i+1][j][3] = max(dp[i+1][j][3],dp[i][j][3] + num[i+1][1] + num[i+1][2]);
    47             dp[i+1][j+1][3] = max(dp[i+1][j+1][3],dp[i][j][1] + num[i+1][1] + num[i+1][2]);
    48             dp[i+1][j+1][3] = max(dp[i+1][j+1][3],dp[i][j][2] + num[i+1][1] + num[i+1][2]);
    49             dp[i+1][j+2][3] = max(dp[i+1][j+2][3],dp[i][j][0] + num[i+1][1] + num[i+1][2]);
    50             dp[i+1][j+2][3] = max(dp[i+1][j+2][3],dp[i][j][4] + num[i+1][1] + num[i+1][2]);
    51             dp[i+1][j][4] = max(dp[i+1][j][4],dp[i][j][4] + num[i+1][1] + num[i+1][2]);
    52             rep(l,0,3) dp[i+1][j+1][4] = max(dp[i+1][j+1][4],dp[i][j][l] + num[i+1][1] + num[i+1][2]);
    53         }
    54     }
    55     ans = max(ans,dp[n][k][0]); ans = max(ans,dp[n][k][1]);
    56     if (m == 2) ans = max(ans,dp[n][k][2]), ans = max(ans,dp[n][k][3]), ans = max(ans,dp[n][k][4]);
    57     printf("%d
    ",ans);
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    Java-数据字符串进行四舍五入
    Git本地安装及汉化
    Navicat安装教程
    Jdk+maven安装
    系列文章
    @PathVariable
    feign组件
    Lombok
    常见Jar包的用途
    iOS archive(归档)的总结
  • 原文地址:https://www.cnblogs.com/jimzeng/p/bzoj1084.html
Copyright © 2020-2023  润新知