【DP专题】——洛谷P2331最大子矩阵

简单的动规题。

传送门:GO


看到这题m<=2,先分类讨论一波:

m=1时,dp[i][j]表示到第i个点,选了j个矩阵的最大子矩阵。

状态转移方程:

  dp[i][j]=dp[t][j-1]+sum[i]-sum[t]

意思是枚举一段区间,将它设为新的矩阵。

m=2时,设dp[i][j][k]表示第i行,状态为j,此时选到k个矩阵时的最大子矩阵。

设计状态:

1.空的

2.只选左边

3.只选右边

4.两边都选,但是左边和右边归为两个子矩阵

5.两边都选,分配到上面

分别讨论状态转移,大致有25个转移方程(好多)

具体看代码就可以了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int read(){
 4     int x=0,f=1;
 5     char c=getchar();
 6     while(!isdigit(c)){
 7         if(c=='-') f=-1;
 8         c=getchar();
 9     }
10     while(isdigit(c)){
11         x=(x<<1)+(x<<3)+(c^48);
12         c=getchar();
13     }
14     return x*f;
15 }
16 const int N=110;
17 int n,m,k;
18 int b[N];
19 int f[N][15][10];
20 int g[N][15];
21 int main(){
22     n=read();m=read();k=read();
23     if(m==1){
24         for(int i=1;i<=n;i++){
25             b[i]=b[i-1]+read();
26         }
27         for(int i=1;i<=k;i++){
28             for(int j=1;j<=n;j++){
29                 g[j][i]=g[j-1][i];
30                 for(int l=1;l<j;l++){
31                     g[j][i]=max(g[j][i],g[l][i-1]+b[j]-b[l]);
32                 }
33             }
34         }
35         printf("%d",g[n][k]);
36         return 0;
37     }
38     else{
39         memset(f,-0x3f,sizeof(f));
40         for(int i=0;i<=n;i++){
41             for(int j=0;j<=k;j++){
42                 f[i][j][0]=0;
43             }
44         }
45         int l,r;
46         for(int i=1;i<=n;i++){
47             l=read();r=read();
48             for(int j=1;j<=k;j++){
49                 f[i][j][0]=max(max(max(max(f[i-1][j][0],f[i-1][j][1]),f[i-1][j][2]),f[i-1][j][3]),f[i-1][j][4]);
50                 f[i][j][1]=max(max(max(max(f[i-1][j-1][0],f[i-1][j][1]),f[i-1][j-1][2]),f[i-1][j][3]),f[i-1][j-1][4])+l;
51                 f[i][j][2]=max(max(max(max(f[i-1][j-1][0],f[i-1][j-1][1]),f[i-1][j][2]),f[i-1][j][3]),f[i-1][j-1][4])+r;
52                 f[i][j][3]=max(max(f[i-1][j-1][1],f[i-1][j-1][2]),f[i-1][j][3])+l+r;
53                 f[i][j][4]=max(max(max(max(f[i-1][j-1][0],f[i-1][j-1][1]),f[i-1][j-1][2]),f[i-1][j-1][3]),f[i-1][j][4])+l+r;
54             }
55         }
56         printf("%d",max(max(max(max(f[n][k][0],f[n][k][1]),f[n][k][2]),f[n][k][3]),f[n][k][4]));
57         return 0;
58     }
59     return 0;
60     
61 } 
——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
原文地址:https://www.cnblogs.com/Nelson992770019/p/11592949.html