zoukankan      html  css  js  c++  java
  • 【BZOJ 1084】 [SCOI2005]最大子矩阵(DP)

    题链

    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个子矩阵分值之和最大为多少。

    Sample Input

    3 2 2
    1 -3
    2 3
    -2 3

    Sample Output

    9

    题解

    注意到m<=2,那么可以分类讨论:
    (1)当m1时,设d1 [ i ] [k]为从考虑前i行找到k个子矩阵,转移方程为
    $ d1[i][k] = max ( d1[i][k] , d1[j][k-1] + sum[i] - sum[j] ) $
    (2)当m
    2时,设d2 [ i ] [ j ] [ k ] 从考虑第一列前i行,第二列前j行找到k个子矩阵,转移方程为
    $ d2[i][j][k]=max(d2[i][j][k],d2[x][j][k-1]+s1[i]-s1[x]);$
    $ d2[i][j][k]=max(d2[i][j][k],d2[i][x][k-1]+s2[j]-s2[x]);$
    $ d2[i][j][k]=max(d2[i][j][k],d2[x][x][k-1]+s1[i]-s1[x]+s2[j]-s2[x]);$

    参考代码

    #include<queue>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    #define inf 1000000000
    #define mod 1000000007
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void Out(ll a) {
        if(a<0) putchar('-'),a=-a;
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=105;
    int d1[N][15],d2[N][N][15];
    int sum[N];
    int s1[N],s2[N];
    int main(){
        int n=read(),m=read(),K=read();
        if(m==1){
            for(int i=1;i<=n;i++){
                int x=read();
                sum[i]=sum[i-1]+x;
            }
            for(int i=1;i<=n;i++) for(int k=1;k<=K;k++){
               d1[i][k]=d1[i-1][k];
               for(int j=i-1;j>=0;j--)
               d1[i][k]=max(d1[i][k],d1[j][k-1]+sum[i]-sum[j]);
            }
            Out(d1[n][K]);
        }
        else{
            for(int i=1;i<=n;i++){
                int x=read(),y=read();
                s1[i]=s1[i-1]+x;
                s2[i]=s2[i-1]+y;
            }
            for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=K;k++){
                d2[i][j][k]=max(d2[i-1][j][k],d2[i][j-1][k]);
                for(int x=0;x<i;x++)  d2[i][j][k]=max(d2[i][j][k],d2[x][j][k-1]+s1[i]-s1[x]);
                for(int x=0;x<j;x++)  d2[i][j][k]=max(d2[i][j][k],d2[i][x][k-1]+s2[j]-s2[x]);
                if(i==j) for(int x=0;x<i;x++)
                d2[i][j][k]=max(d2[i][j][k],d2[x][x][k-1]+s1[i]-s1[x]+s2[j]-s2[x]);
            }
            Out(d2[n][n][K]);
        }
        return 0;
    }
    
    
  • 相关阅读:
    【总结】编写自己的JDBC框架
    笔者带你剖析淘宝TDDL(TAOBAO DISTRIBUTE DATA LAYER)
    高性能jdbc封装工具 Apache Commons DbUtils 1.6(转载)
    简单通用JDBC辅助类封装
    word2010中怎样快速修改同级标题格式
    怎么批量修改Word表格的宽度
    MS WORD 表格自动调整列宽,自动变漂亮,根据内容自动调整 .
    PowerDesiger 15逆向生成工程E-R图及导出word表格
    PowerDesigner-自定义生成WORD
    PowerDesigner如何自定义报表模板
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/7152909.html
Copyright © 2011-2022 走看看