bzoj 1084: [SCOI2005]最大子矩阵

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

解题报告:这数据范围就看出是个SBT,但本人太菜,写的又丑又长,复杂度又高.
定义f[i][j][k]表示第一列的前i列第二行的前j列都处理完,一共选出了k个的最大分值之和,这个显然是很好转移的:枚举矩阵大小和形状,然后分情况转移即可
复杂度\(O(n^3k)\)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=105,inf=2e8;
int f[N][N][15],a[N][3],g[3][N][N],xy[N][N];
void work()
{
	int n,m,K;
	scanf("%d%d%d",&n,&m,&K);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	for(int j=1;j<=2;j++){
		//g[j][i][k]表示第j列的i-k一段的最大子段和
		for(int i=1;i<=n;i++){
			for(int k=1;k<=i;k++){
				int tot=0,ret=-inf;
				for(int l=i;l>=k;l--){
					if(tot<0)tot=a[l][j];
					else tot+=a[l][j];
					if(tot>ret)ret=tot;
				}
				g[j][k][i]=ret;
			}
		}
	}
	for(int i=1;i<=n;i++){
		//xy[i][j]表示前两列一起时 i-j的最大子段和
		for(int k=1;k<=i;k++){
			int tot=0,ret=-inf;
			for(int l=i;l>=k;l--){
				if(tot<0)tot=a[l][1]+a[l][2];
				else tot+=a[l][1]+a[l][2];
				if(tot>ret)ret=tot;
			}
			xy[k][i]=ret;
		}
	}
	int s,ans=-inf;
	for(int k=0;k<K;k++)
		for(int i=0;i<=n;i++){
			for(int j=0;j<=n;j++){
				f[i][j][k+1]=Max(f[i][j][k+1],f[i][j][k]);
 				s=Max(i,j)+1;
				for(int l=s;l<=n;l++){
					f[l][l][k+1]=Max(f[l][l][k+1],f[i][j][k]+xy[s][l]);
				}
				for(int l=i+1;l<=n;l++)
					f[l][j][k+1]=Max(f[l][j][k+1],f[i][j][k]+g[1][i+1][l]);
				for(int l=j+1;l<=n;l++)
					f[i][l][k+1]=Max(f[i][l][k+1],f[i][j][k]+g[2][j+1][l]);
			}
		}
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			ans=Max(ans,f[i][j][K]);
	printf("%d\n",ans);
}
int main()
{
	freopen("pp.in","r",stdin);
	freopen("pp.out","w",stdout);
 	work();
	return 0;
}
posted @ 2017-09-05 20:38  PIPIBoss  阅读(162)  评论(0编辑  收藏  举报