題目描述 這裡有一個n*m的矩陣,請你選出其中k個子矩陣,使得這個k個子矩陣分值之和最大。註意:選出的k個子矩陣不能相互重疊。 輸入輸出格式 輸入格式: 第一行為n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下來n行描述矩陣每行中的每個元素的分值(每個元素的分值的絕對值不超過32767) ...
題目描述
這裡有一個n*m的矩陣,請你選出其中k個子矩陣,使得這個k個子矩陣分值之和最大。註意:選出的k個子矩陣不能相互重疊。
輸入輸出格式
輸入格式:
第一行為n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下來n行描述矩陣每行中的每個元素的分值(每個元素的分值的絕對值不超過32767)。
輸出格式:
只有一行為k個子矩陣分值之和最大為多少。
輸入輸出樣例
輸入樣例#1:3 2 2 1 -3 2 3 -2 3輸出樣例#1:
9
讀完題目之後我們可以發現:
這個數據的m==2.
那麼就簡單了。
我們用dp[i][j][k]
表示第一列取到i,第二列取到j,取了k個矩陣的最大值、。
然後首碼和優化一下。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<queue> 6 #include<algorithm> 7 #include<cstdlib> 8 #define lli long long int 9 using namespace std; 10 void read(int &n) 11 { 12 char c='+';int x=0;bool flag=0; 13 while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} 14 while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();} 15 flag==1?n=-x:n=x; 16 } 17 const int MAXN=101; 18 int n,m,k; 19 int dp[MAXN][MAXN][MAXN]; 20 int sum[MAXN][3]; 21 int two[MAXN]; 22 int a[MAXN][MAXN]; 23 24 int main() 25 { 26 read(n);read(m);read(k); 27 for(int i=1;i<=n;i++) 28 for(int j=1;j<=m;j++) 29 read(a[i][j]); 30 for(int i=1;i<=n;i++) 31 for(int j=1;j<=m;j++) 32 sum[i][j]=sum[i-1][j]+a[i][j]; 33 for(int i=1;i<=n;i++) 34 two[i]=two[i-1]+a[i][1]+a[i][2]; 35 for(int i=1;i<=n;i++) 36 for(int j=1;j<=n;j++) 37 for(int l=k;l>=1;l--) 38 { 39 dp[i][j][l]=max(dp[i][j-1][l],dp[i-1][j][l]); 40 for(int h=1;h<=i;h++)//往前掃描 41 dp[i][j][l]=max(dp[i][j][l],dp[h-1][j][l-1]+sum[i][1]-sum[h-1][1]); 42 for(int h=1;h<=j;h++)//往前掃描 43 dp[i][j][l]=max(dp[i][j][l],dp[i][h-1][l-1]+sum[j][2]-sum[h-1][2]); 44 for(int h=1;h<=min(i,j);h++) 45 dp[i][j][l]=max(dp[i][j][l],dp[h-1][h-1][l-1]+two[min(i,j)]-two[h-1]); 46 } 47 printf("%d",dp[n][n][k]); 48 return 0; 49 }