zoukankan      html  css  js  c++  java
  • BZOJ 1084 最大子矩阵 终于过了

       一开始看到这道题,由于觉得m <= 2, 所以觉得这是道水题,回去后想了一下。在晚上来机房的时候已经想出来了,但是我必须承认细节决定成败。远在一个小时前我就已经把算法的主体都写好了,但是就是一直WA,为什么就是各种粗心,真心想捏死自己。一个小时就这么白白浪费了。我希望明天的我能变得强大一点。在有了今日惨痛的教训之后。

       这道题并不难。用d[i][j][k] 来表示状态。i表示第几行,j表示之前取了多少个矩阵,k表示上一行的状态。即上一行的矩阵取法。如果k == 0 那么没有一个矩阵延伸到上一行,如果 k == 1,那么有一个矩阵延伸到上一行的左边那个数, k == 2 时 那么有一个矩阵延伸到上一行的右边那个数, k == 3 时分别有两个矩阵延伸到上一个的两个数。当k == 4 时有一个矩阵延伸到上一行的两个数。那么状态转移方程应该就不难写了。细心细心,再细心。谦虚,谦虚,再谦虚。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define INF 0x3fffffff
     5 #define rep(i,j,k) for(int i = j; i <= k; i++)
     6 #define maxn 120
     7 using namespace std;
     8 
     9 int d[maxn][15][5] = {0};
    10 int a[maxn][3] = {0};
    11 
    12 int read()
    13 {
    14     int s = 0, t = 1; char c = getchar();
    15     while( !isdigit(c) ){
    16         if( c == '-' ) t = -1; c = getchar();
    17     }
    18     while( isdigit(c) ){
    19         s = s * 10 + c - '0'; c = getchar();
    20     }
    21     return s * t;
    22 }
    23 
    24 int main()
    25 {
    26     int n = read(), m = read(), k = read();
    27     rep(i,0,n) rep(j,0,k) rep(l,0,4) d[i][j][l] = -INF;
    28     d[0][0][0] = 0;
    29     rep(i,1,n){
    30         rep(j,1,m){
    31             a[i][j] = read();
    32         }
    33     }
    34       rep(i,0,n-1)
    35           rep(j,0,k){
    36            if( m == 1 ){
    37                rep(l,0,1) d[i+1][j][0] = max(d[i+1][j][0],d[i][j][l]);
    38                d[i+1][j][1] = max(d[i+1][j][1],d[i][j][1]+a[i+1][1]);
    39                d[i+1][j+1][1] = max(d[i+1][j+1][1],d[i][j][0]+a[i+1][1]);
    40            }
    41            else{
    42                rep(l,0,4) d[i+1][j][0] = max(d[i+1][j][0],d[i][j][l]);
    43                d[i+1][j][1] = max(d[i+1][j][1],d[i][j][1]+a[i+1][1]);
    44                d[i+1][j][1] = max(d[i+1][j][1],d[i][j][3]+a[i+1][1]);
    45                d[i+1][j+1][1] = max(d[i+1][j+1][1],d[i][j][0]+a[i+1][1]);
    46                d[i+1][j+1][1] = max(d[i+1][j+1][1],d[i][j][2]+a[i+1][1]);
    47                d[i+1][j+1][1] = max(d[i+1][j+1][1],d[i][j][4]+a[i+1][1]);
    48                
    49                d[i+1][j][2] = max(d[i+1][j][2],d[i][j][2]+a[i+1][2]);
    50                d[i+1][j][2] = max(d[i+1][j][2],d[i][j][3]+a[i+1][2]);
    51                d[i+1][j+1][2] = max(d[i+1][j+1][2],d[i][j][0]+a[i+1][2]);
    52                d[i+1][j+1][2] = max(d[i+1][j+1][2],d[i][j][1]+a[i+1][2]);
    53                d[i+1][j+1][2] = max(d[i+1][j+1][2],d[i][j][4]+a[i+1][2]);
    54                
    55                d[i+1][j][3] = max(d[i+1][j][3],d[i][j][3]+a[i+1][2]+a[i+1][1]);
    56                d[i+1][j+1][3] = max(d[i+1][j+1][3],d[i][j][1]+a[i+1][2]+a[i+1][1]);
    57                d[i+1][j+1][3] = max(d[i+1][j+1][3],d[i][j][2]+a[i+1][2]+a[i+1][1]);
    58                d[i+1][j+2][3] = max(d[i+1][j+2][3],d[i][j][0]+a[i+1][2]+a[i+1][1]);
    59                d[i+1][j+1][3] = max(d[i+1][j+1][3],d[i][j][4]+a[i+1][2]+a[i+1][1]);
    60                
    61                d[i+1][j][4] = max(d[i+1][j][4],d[i][j][4]+a[i+1][2]+a[i+1][1]);
    62                rep(l,0,3) d[i+1][j+1][4] = max(d[i+1][j+1][4],d[i][j][l]+a[i+1][2]+a[i+1][1]);
    63            }
    64       }
    65       int ans;
    66       ans = max(d[n][k][0],d[n][k][1]);
    67       if( m == 2 ) rep(l,2,4) ans = max(ans,d[n][k][l]);
    68       cout<<ans<<endl;
    69       return 0;
    70 }

    1084: [SCOI2005]最大子矩阵

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1851  Solved: 927
    [Submit][Status][Discuss]

    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
    人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方
  • 相关阅读:
    HDU 2899 Strange fuction
    HDU 2899 Strange fuction
    HDU 2199 Can you solve this equation?
    HDU 2199 Can you solve this equation?
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 699 掉落的方块(线段树?)
    Java实现 LeetCode 699 掉落的方块(线段树?)
    Java实现 LeetCode 699 掉落的方块(线段树?)
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5049515.html
Copyright © 2011-2022 走看看