BZOJ 1084DP

1084: [SCOI2005]最大子矩阵

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2796  Solved: 1391
[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
 
 
题解感觉是按最多K个做的并且过了。。那题目就当成是最多K个吧
 
 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[111][111][11],dp[111][11];
int x1,x2;
int sum1[111],sum2[111];
int main()
{
    int n,m,K;
    scanf("%d%d%d",&n,&m,&K);
    if(m==1)
    {
        for(int i=1; i<=n; ++i)
        {
            scanf("%d",&x1);
            sum1[i]=sum1[i-1]+x1;
        }
        for(int i=1; i<=n; ++i)
        {
            for(int k=1; k<=K; ++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]+sum1[i]-sum1[j]);
            }
        }
        printf("%d\n",dp[n][K]);
    }
    else
    {
        for(int i=1; i<=n; ++i)
        {
            scanf("%d%d",&x1,&x2);
            sum1[i]=sum1[i-1]+x1;
            sum2[i]=sum2[i-1]+x2;
        }
        for(int k=1; k<=K; ++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]+sum1[i]-sum1[l]);
                    for(int l=0; l<j; ++l)
                        f[i][j][k]=max(f[i][j][k],f[i][l][k-1]+sum2[j]-sum2[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]+sum1[i]-sum1[l]+sum2[j]-sum2[l]);
                }
            }
        }
        printf("%d\n",f[n][n][K]);
    }
}
posted @ 2017-07-07 15:25  Billyshuai  阅读(117)  评论(0编辑  收藏  举报