zoukankan      html  css  js  c++  java
  • P2331 [SCOI2005]最大子矩阵

    我是题面

    题面这么简洁,清晰,易懂,真是不可多得的良心题面(比我上一篇博客那道题良心多了

    我们会发现m只有2

    如果m是一个较大的数的话可能会麻烦一点,只有2的话就很好做了

    我们先来考虑m为1的情况,很简单,(f[i][j][0/1])表示是否选第i个,已经选了j个连续矩形,最大为多少,直接dp即可

    那么如果m为2的话,有5种情况

    (f[i][j][k])表示第i行为第k种情况,有j个矩形,最大为多少

    第一种:两个都不选,空出这一行

    第二种:选左边,不选右边

    第三种:选右边,不选左边

    第四种:左右都选,但是不属于同一矩形

    第五种:左右都选,属于同一矩形

    分出这五种情况来,这道题就A了

    下面放代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cctype>
    #define ll long long
    #define gc getchar
    #define maxn 105
    #define maxm 15
    using namespace std;
    
    inline ll read(){
        ll a=0;int f=0;char p=gc();
        while(!isdigit(p)){f|=p=='-';p=gc();}
        while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
        return f?-a:a;
    }int n,m,k,a[maxn][maxn],f[maxn][maxm][5];
    
    int main(){
        n=read();m=read();k=read();
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                a[i][j]=read();
        if(m==1){
            for(int i=1;i<=n;++i)
                for(int j=1;j<=k;++j){
                    f[i][j][0]=max(f[i-1][j][1],f[i-1][j][0]);
                    f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][0])+a[i][1];
                }
            printf("%d
    ",max(f[n][k][0],f[n][k][1]));
            return 0;
        }memset(f,~63,sizeof f);
        for(int i=0;i<=n;++i)
            for(int j=0;j<=k;++j)
                f[i][j][0]=0;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=k;++j){
                f[i][j][0]=max(f[i-1][j][0],max(max(f[i-1][j][1],f[i-1][j][2]),max(f[i-1][j][3],f[i-1][j][4])));
                f[i][j][1]=max(f[i-1][j-1][0],max(max(f[i-1][j][1],f[i-1][j][3]),max(f[i-1][j-1][2],f[i-1][j-1][4])))+a[i][1];
                f[i][j][2]=max(f[i-1][j-1][0],max(max(f[i-1][j][2],f[i-1][j][3]),max(f[i-1][j-1][1],f[i-1][j-1][4])))+a[i][2];
                f[i][j][3]=max(max(f[i-1][j-1][1],f[i-1][j-1][2]),f[i-1][j][3]);
                f[i][j][4]=max(f[i-1][j][4],max(max(f[i-1][j-1][0],f[i-1][j-1][1]),max(f[i-1][j-1][2],f[i-1][j-1][3])))+a[i][1]+a[i][2];
                if(j>=2)f[i][j][3]=max(f[i][j][3],max(f[i-1][j-2][0],f[i-1][j-2][4]));
                f[i][j][3]+=a[i][1]+a[i][2];
            }
        printf("%d
    ",max(f[n][k][0],max(max(f[n][k][1],f[n][k][2]),max(f[n][k][3],f[n][k][4]))));
        return 0;
    }
    
  • 相关阅读:
    Beta 冲刺(7/7)
    Beta 冲刺(6/7)
    Beta 冲刺(5/7)
    Beta 冲刺(4/7)
    Beta 冲刺(3/7)
    Beta 冲刺(2/7)
    Beta 冲刺(1/7)
    福大软工 · 第十次作业
    Adobe acrobat DC 2020 激活方法
    物理八年级下册2
  • 原文地址:https://www.cnblogs.com/hanruyun/p/10270130.html
Copyright © 2011-2022 走看看