【BZOJ 1084】 1084: [SCOI2005]最大子矩阵 (DP)

1084: [SCOI2005]最大子矩阵

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

HINT

 

 

【分析】

  终于考完ws的期末考回来刷题了,表示很桑心先刷一道水题淡定一下。。。

  表示又是智障看错了以为k是100。

  思路很简单,m<=2,分m=1 m=2两种情况讨论。

  m=1:

  f[i][j]表示选了前i个数,j个矩阵的最优值,枚举最后一个矩阵转移。

  m=2:

  f[i][j][k]表示第一行选了前i个数,第二行选了前j个数,一共k个矩阵的最优值。

  状态:1、枚举第一行最后一个矩阵。

     2、枚举第二行最后一个矩阵。

     3、当i=j,可以两行一起选,枚举两行一起选的最后一个矩阵。

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 110
 8 
 9 int a[2][Maxn],h[2][Maxn],f[Maxn][Maxn];
10 int d[Maxn][Maxn][Maxn];
11 
12 int mymax(int x,int y) {return x>y?x:y;}
13 
14 int main()
15 {
16     int n,m,k;
17     scanf("%d%d%d",&n,&m,&k);
18     for(int i=1;i<=n;i++)
19      for(int j=0;j<m;j++) scanf("%d",&a[j][i]);
20     h[0][0]=h[1][0]=0;
21     for(int i=0;i<m;i++)
22      for(int j=1;j<=n;j++) h[i][j]=h[i][j-1]+a[i][j];
23     int ans=0;
24     if(m==1)
25     {
26         memset(f,0,sizeof(f));
27         for(int i=1;i<=n;i++)
28          for(int j=1;j<=i&&j<=k;j++)
29          {
30              for(int l=0;l<i;l++)
31                 f[i][j]=mymax(f[i][j],f[l][j-1]+h[0][i]-h[0][l]);
32             f[i][j]=mymax(f[i][j],f[i-1][j]);
33          }
34         for(int i=k;i<=n;i++) ans=mymax(ans,f[i][k]);
35     }
36     else
37     {
38         memset(d,0,sizeof(d));
39         for(int i=0;i<=n;i++)
40          for(int j=0;j<=n;j++)
41           for(int l=1;l<=k;l++)
42           {
43               for(int p=0;p<i;p++) d[i][j][l]=mymax(d[i][j][l],d[p][j][l-1]+h[0][i]-h[0][p]);
44               for(int p=0;p<j;p++) d[i][j][l]=mymax(d[i][j][l],d[i][p][l-1]+h[1][j]-h[1][p]);
45               if(i==j)
46               {
47                   for(int p=0;p<i;p++) d[i][j][l]=mymax(d[i][j][l],d[p][p][l-1]+h[0][i]+h[1][j]-h[0][p]-h[1][p]);
48               }
49               d[i][j][l]=mymax(d[i][j][l],d[i-1][j][l]);
50               d[i][j][l]=mymax(d[i][j][l],d[i][j-1][l]);
51               if(l==k) ans=mymax(ans,d[i][j][l]);
52               // printf("d[%d][%d][%d]= %d\n",i,j,l,d[i][j][l]);
53           }
54     }
55     printf("%d\n",ans);
56     return 0;
57 }
View Code

 

2017-01-11 09:11:39

posted @ 2017-01-11 09:05  konjak魔芋  阅读(78)  评论(0编辑  收藏