首页 > 代码库 > BZOJ: 1084: [SCOI2005]最大子矩阵

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     else31         {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

 

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