• [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;
    }
  • 相关阅读:
    (React 框架)React技术
    React 项目
    JS语法之--模块化
    JS 语法之-- 解构,Promise(异步)
    JS 语法之--对象类型(构造器,class,this),高阶对象(高阶类,Minix模式)
    javascript:console对象与控制台
    javascript:错误处理
    javascript:基本数据类型转换
    javascript:数据结构-数组
    javascript:数据结构-对象
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4643212.html
Copyright © 2020-2023  润新知