P2331 [SCOI2005] Maximum submatrix

Topic description

Here is an n*m matrix, please select k sub-matrices so that the sum of the scores of the k sub-matrices is the largest. Note: The selected k sub-matrices cannot overlap each other.

Input and output format

Input format:

The first row is n, m, k (1≤n≤100, 1≤m≤2, 1≤k≤10), and the next n rows describe the score of each element in each row of the matrix (the score of each element is The absolute value of the value does not exceed 32767). 

Output format: 

Only one row is the maximum sum of the k submatrix scores.

 

Input and output example

Input example #1: 
3 2 2
1 -3
2 3
-2 3
Sample output #1: 
  9
 

Solution

As a provincial election DP, this question is relatively simple.
But it's still a bit difficult to think about.
Get first look at m , m is only 1 and 2 ?
So let's start with the case of m=1.
 
Status Definition:
f[i][l] means that the maximum value of l rectangles is used up to the ith point.

Transition equation: 
for(pre 1--> i-1)
f[i][l]=max(f[i-1][l],f[pre][l-1]+sum[pre--> i]);
//sum represents the sum of the element values ​​from pre to i.

So m=1 has 30 pts.

 

Then think about m=2 and expand from m=1?

So define the state : f[ i ][ j ][ l ] means that the upper column goes to the lower column of i to the maximum value of the selected l matrices of j.

After thinking about it, m=2 has the following situations:

1. I do not expand this point --> max( f[ i-1 ][ j-1 ][ l ] , f[ i-1 ][ j-1 ][ l ] ,f[ i ][ j- 1][l]); 

2. Extend a small s*1 area from the previous column

3. Extend a small s*1 area from the previous column

4. Both columns are extended to get an area of ​​s*2

 

As a result, the DP of this question naturally came out.

 

code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,k;
 4 int f1[105][11],f[105][105][11];
 5 int c[2][105],sum[2][105];
 6 
 7 void solve()    
 8 {
 9     for(int i=1;i<=n;i++)
10     for(int l=1;l<=k;l++) 
11         { 
12             f1[i][l]=f1[i-1][l];
13             for(int j=0;j<i;j++)
14             f1[i][l]=max(f1[j][l-1]+sum[1][i]-sum[1][j],f1[i][l]);
15         }
16     cout<<f1[n][k];
17     return;
18 }
19 
20 
21 int main()
22 {
23     cin>>n>>m>>k;
24     for(int i=1;i<=n;i++)
25     for(int j=1;j<=m;j++)
26     scanf("%d",&c[j][i]),sum[j][i]=sum[j][i-1]+c[j][i];
27     if(m==1) {solve();return 0;}
28     
29     for(int l=1;l<=k;l++)
30     for(int i=1;i<=n;i++)
31     for(int j=1;j<=n;j++) 
32     {
33             f[i][j][l]=max(f[i-1][j][l],f[i][j-1][l]);
34             for(int pre=0;pre<i;pre++) f[i][j][l]=max(f[i][j][l],f[pre][j][l-1]+sum[1][i]-sum[1][pre]);
35             for(int pre=0;pre<j;pre++) f[i][j][l]=max(f[i][j][l],f[i][pre][l-1]+sum[2][j]-sum[2][pre]);
36             if(i==j)
37             for(int pre=0;pre<i;pre++)
38             f[i][j][l]=max(f[i][j][l],f[pre][pre][l-1]+sum[1][i]-sum[1][pre]+sum[2][j]-sum[2][pre]);
39     }
40     cout<<f[n][n][k];
41 
42     return 0;
43 }

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325971345&siteId=291194637