BZOJ: 1084: [SCOI2005]最大子矩阵

NICE 的DP 题,明白了题解真是不错。

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1228  Solved: 622
[Submit][Status]

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

思路:M<=2;

先是M==1的情况 这个是满满的三维。DP[I][J】表示做的第几个,现在做到J个数了。转移也比较简单。

M==2时,

我们要加一维。

具体是这样:F[I][J][K] 表示做第I个 J 表示上面做到第几,K表示下面做到第几。

转移方程:具体见代码。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 123
 4 int s[N];
 5 int s1[N];
 6 int s2[N];
 7 int a[N];
 8 int dp[N][N];
 9 int f[N][N][N];
10 int main()
11 {
12     int n;
13     int k;
14     int m;
15     scanf("%d%d%d",&n,&m,&k);
16     if (m==1){
17              for (int i=1;i<=n;i++) {
18              scanf("%d",&a[i]);
19              s[i]=s[i-1]+a[i];
20              }
21             for (int i=1;i<=k;i++)
22             for (int j=1;j<=n;j++)
23             {
24             dp[i][j]=dp[i][j-1];
25             for (int p=0;p<j;p++)
26             dp[i][j]=max(dp[i][j],dp[i-1][p]+s[j]-s[p]);
27            }
28            printf("%d\n",dp[k][n]);
29       }
30     else
31         {
32             for (int i=1;i<=n;i++)
33             {
34                 int x1,x2;
35                 scanf("%d%d",&x1,&x2);
36                 s1[i]+=s1[i-1]+x1;
37                 s2[i]+=s2[i-1]+x2;
38             }
39 
40             for (int i=1;i<=k;i++)
41             for (int j=1;j<=n;j++)
42             for (int p=1;p<=n;p++)
43             {
44                 f[i][j][p]=max(f[i][j-1][p],f[i][j][p-1]);
45                 for (int l=0;l<j;l++)
46                 f[i][j][p]=max(f[i][j][p],f[i-1][l][p]+s1[j]-s1[l]);
47 
48                 for (int l=0;l<p;l++)
49                 f[i][j][p]=max(f[i][j][p],f[i-1][j][l]+s2[p]-s2[l]);
50 
51                 if (j==p)
52                 {
53                    for (int l=0;l<j;l++)
54                     f[i][j][p]=max(f[i][j][p],f[i-1][l][l]+s2[p]-s2[l]+s1[p]-s1[l]);
55                 }
56             }
57 
58             printf("%d\n",f[k][n][n]);
59         }
60     return 0;
61 }
View Code

 

posted on 2014-11-11 20:37  forgot93  阅读(168)  评论(0编辑  收藏  举报

导航