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

    1084: [SCOI2005]最大子矩阵

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1533  Solved: 773
    [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
     
    1<=m<=2。。。。
    直接分类讨论,不过m=2的想法确实比较奇怪(或许我见识少)没想出来。。m=1就很弱了。
    首先无论m等于几,对于每列都要维护前缀和。m=1时,容易想到f[i][k]表示前i个分成j段(要注意各段是可以相邻的),f[i][k]=max(f[j][k-1]+sum[i]-sum[j])(j<i)。最后输出f[n][k];
    对于m=2时,f[i][j][k]表示第一列的前i行,第二列的前j行,分成k个子矩阵的最大和,f[i][j][k]=max(f[l][j][k-1]+s1[i]-s1[l],f[i][l][k-1]+s2[j]-s2[l])(l<i;l<j;i!=j) f[i][j][k]=max(f[l][j][k-1]+s1[i]-s1[l],f[i][l][k-1]+s2[j]-s2[l],f[l][l]+s1[i]-s1[l]+s2[j]-s2[l])(l<i;l<j,i=j);最后输出f[n][n][k];
     
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,m,kk,a[1001],b[1001],s[1001],s1[1001],s2[1001],dp[1001][11],f[1001][1001][11];
    int main()
    {
        scanf("%d%d%d",&n,&m,&kk);
        if (m==1)
        {
            for (int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                s[i]=s[i-1]+a[i];
            }
            for (int i=1;i<=n;i++)
                for (int k=1;k<=kk;k++)
                {
                    dp[i][k]=dp[i-1][k];
                    for (int j=0;j<i;j++)
                        dp[i][k]=max(dp[i][k],dp[j][k-1]+s[i]-s[j]);
                }
            printf("%d",dp[n][kk]);
        }
        if (m==2)
        {
            for (int i=1;i<=n;i++)
            {
                scanf("%d%d",&a[i],&b[i]);
                s1[i]=s1[i-1]+a[i];
                s2[i]=s2[i-1]+b[i];
            }
            for (int k=1;k<=kk;k++)
                for (int i=1;i<=n;i++)
                    for (int j=1;j<=n;j++)
                    {
                        f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]);
                        for (int l=0;l<i;l++) f[i][j][k]=max(f[i][j][k],f[l][j][k-1]+s1[i]-s1[l]);
                        for (int l=0;l<j;l++) f[i][j][k]=max(f[i][j][k],f[i][l][k-1]+s2[j]-s2[l]);
                        if (i==j)
                            for (int l=0;l<i;l++) f[i][j][k]=max(f[i][j][k],f[l][l][k-1]+s1[i]-s1[l]+s2[j]-s2[l]);
                    }
            printf("%d",f[n][n][kk]);
        }
        return 0;
    }
  • 相关阅读:
    洛谷P3959 宝藏(状压dp)
    洛谷P3645 [APIO2015]雅加达的摩天楼(最短路+分块)
    洛谷P3646 [APIO2015]巴厘岛的雕塑(数位dp)
    洛谷P4770 [NOI2018]你的名字(后缀自动机+线段树)
    洛谷P4768 [NOI2018]归程(克鲁斯卡尔重构树+最短路)
    hive3.1.1 hive-site.xml
    mysql 远程连接数据库的二种方法
    linux彻底干干净净完全卸载 mysql
    jdk环境变量配置
    Eclipse常用快捷键
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4643212.html
Copyright © 2011-2022 走看看