1084: [SCOI2005]最大子矩阵

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3621  Solved: 1819
[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列的情况
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 
 5 int n,m,K;
 6 int sum[101],f[101][11];
 7 int a[101],b[101],c[101][101][11];
 8 
 9 void solve1()
10 {
11     for(int i=1;i<=n;i++)
12     {
13         int x;
14         scanf("%d",&x);
15         sum[i]=sum[i-1]+x;
16     }
17     for(int i=1;i<=n;i++)
18         for(int k=1;k<=K;k++)
19         {
20             f[i][k]=f[i-1][k];
21             for(int j=0;j<i;j++)
22                 f[i][k]=max(f[i][k],f[j][k-1]+sum[i]-sum[j]);
23         }
24     printf("%d
",f[n][K]);
25 }
26 
27 void solve2()
28 {
29     for(int i=1;i<=n;i++)
30     {
31         int x,y;
32         scanf("%d %d",&x,&y);
33         a[i]=a[i-1]+x;b[i]=b[i-1]+y;
34     }
35     for(int k=1;k<=K;k++)
36         for(int i=1;i<=n;i++)
37             for(int j=1;j<=n;j++)
38             {
39                 c[i][j][k]=max(c[i-1][j][k],c[i][j-1][k]);
40                 for(int l=0;l<i;l++) c[i][j][k]=max(c[i][j][k],c[l][j][k-1]+a[i]-a[l]);
41                 for(int l=0;l<j;l++) c[i][j][k]=max(c[i][j][k],c[i][l][k-1]+b[j]-b[l]);
42                 if(i==j)
43                     for(int l=0;l<i;l++) c[i][j][k]=max(c[i][j][k],c[l][l][k-1]+a[i]-a[l]+b[j]-b[l]);
44             }
45     printf("%d
",c[n][n][K]);
46 }
47 
48 int main()
49 {
50     scanf("%d %d %d",&n,&m,&K);
51     if(m==1) solve1();
52     else solve2();
53     return 0;
54 }
原文地址:https://www.cnblogs.com/InWILL/p/9439302.html