A - 最大子矩阵 HYSBZ - 1084 (DP)
题目链接:https://cn.vjudge.net/contest/281963#problem/A
题目大意:中文题目
具体思路:观察到m<=2,所以我们可以对两种情况进行单独讨论,当m==1时,dp[i][j]表示将前i行分成j组的最大值,所以最终输出dp[n][k]就可以了。在每一次递推的时候就看一下前面的i-1行的分成j-1组的最大值+a[i]-a[L]就可以了。当m==2的时候,就把他看成单独的两列进行求解就可以了。
AC代码:
1 #include<iostream> 2 #include<stack> 3 #include<cmath> 4 #include<stdio.h> 5 #include<queue> 6 #include<algorithm> 7 using namespace std; 8 # define ll long long 9 const int maxn = 100+100; 10 int dp1[maxn][maxn]; 11 int dp[maxn][maxn][maxn]; 12 int a[maxn],b[maxn]; 13 int main() 14 { 15 int n,m,k,t1,t2; 16 scanf("%d %d %d",&n,&m,&k); 17 if(m==1) 18 { 19 for(int i=1; i<=n; i++) 20 { 21 scanf("%d",&t1); 22 a[i]=a[i-1]+t1; 23 } 24 for(int i=1; i<=n; i++) 25 { 26 for(int j=1; j<=k; j++) 27 { 28 dp1[i][j]=dp1[i-1][j]; 29 for(int L=0; L<i; L++) 30 { 31 dp1[i][j]=max(dp1[i][j],dp1[L][j-1]+a[i]-a[L]); 32 } 33 } 34 } 35 printf("%d\n",dp1[n][k]); 36 } 37 else 38 { 39 for(int i=1; i<=n; i++) 40 { 41 scanf("%d %d",&t1,&t2); 42 a[i]=a[i-1]+t1; 43 b[i]=b[i-1]+t2; 44 } 45 for(int i=1; i<=k; i++) 46 { 47 for(int i1=1; i1<=n; i1++) 48 { 49 for(int j1=1; j1<=n; j1++) 50 { 51 dp[i1][j1][i]=max(dp[i1-1][j1][i],dp[i1][j1-1][i]); 52 for(int L=0; L<i1; L++) 53 { 54 dp[i1][j1][i]=max(dp[i1][j1][i],dp[L][j1][i-1]+a[i1]-a[L]); 55 } 56 for(int L=0; L<j1; L++) 57 { 58 dp[i1][j1][i]=max(dp[i1][j1][i],dp[i1][L][i-1]+b[j1]-b[L]); 59 } 60 if(i1==j1) 61 { 62 for(int L=0; L<i1; L++) 63 { 64 dp[i1][j1][i]=max(dp[i1][j1][i],dp[L][L][i-1]+a[i1]-a[L]+b[i1]-b[L]); 65 } 66 } 67 } 68 } 69 } 70 printf("%d\n",dp[n][n][k]); 71 } 72 return 0; 73 }