zoukankan      html  css  js  c++  java
  • bzoj1084: [SCOI2005]最大子矩阵(dp)

    1084: [SCOI2005]最大子矩阵

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2865  Solved: 1428
    [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
     
    /*
    这题因为m只有1、2两种情况,所以分开讨论。
    m=1 这部分还是比较水的,f[i][j]表示前i行选j个矩形的最大分值。
    方程f[i][j]=max(f[i-1][j],max{f[k][j-1]+sum[i]-sum[k]|0<=k<=i})(sum是前缀和)
    * m=2
    f[i][j][k]表示第一列前i行,第二列前j行选k个矩形的最大分值,方程和m=1是较相似,但多了i=j时的情况,
    叙述比较麻烦,具体看代码。
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 105
    
    using namespace std;
    int dp[N][N][N],f[N][N],s[N][2],sum[N],a[N],b[N];
    int n,m,k,ans;
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        if(m==1)
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                sum[i]=sum[i-1]+a[i];
            }
            for(int i=1;i<=n;i++)
            {
                f[i][0]=0;
                for(int j=1;j<=k;j++)
                {
                    f[i][j]=f[i-1][j];
                    for(int l=1;l<=i;l++)
                      f[i][j]=max(f[i][j],f[l][j-1]+sum[i]-sum[l]);
                }
            }
            printf("%d
    ",f[n][k]);
        }    
        
        else
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&a[i],&b[i]);
                s[i][0]=s[i-1][0]+a[i];
                s[i][1]=s[i-1][1]+b[i];
            }
            for(int i1=1;i1<=n;i1++) for(int i2=1;i2<=n;i2++)
            {
                dp[i1][i2][0]=0;
                for(int j=1;j<=k;j++)
                {
                    dp[i1][i2][j]=max(dp[i1-1][i2][j],dp[i1][i2-1][j]);
                    for(int l=0;l<i1;l++)
                      dp[i1][i2][j]=max(dp[i1][i2][j],dp[l][i2][j-1]+s[i1][0]-s[l][0]);
                    for(int l=0;l<i2;l++)
                      dp[i1][i2][j]=max(dp[i1][i2][j],dp[i1][l][j-1]+s[i2][1]-s[l][1]);
                    if(i1==i2)
                    {
                        for(int l=0;l<i1;l++)
                          dp[i1][i2][j]=max(dp[i1][i2][j],dp[l][l][j-1]+s[i1][0]-s[l][0]+s[i2][1]-s[l][1]);
                    }
                }
            }
            printf("%d
    ",dp[n][n][k]);
        }
        return 0;
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    深入Python(一)
    深入Python(二)
    初识Python(五)
    初识Python(一)
    深入Python(三)
    一、MongoDB的下载、安装与部署
    浏览器上的javascript
    javascript中的事件
    扩展方法
    团队项目开题报告
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7354794.html
Copyright © 2011-2022 走看看