[bzoj1084][SCOI2005]最大子矩陣 dp

1084: [SCOI2005]最大子矩陣

Time Limit: 10 Sec  Memory Limit: 162 MB
[Submit][Status][Discuss]

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

HINT

數據只有兩行
dp[i][j][k]遍歷到第一行i個,第二行j個,生成了k個矩形
1行特判,好像不好優化的樣子
我開始竟然搞忘寫兩行的情況了,naive
#include <bits/stdc++.h>
using namespace std;
int n, m, k, f[105][15], dp[105][105][15], s1[105], s2[105];
int main(){
	scanf( "%d%d%d", &n, &m, &k );
	if( m == 1 ){
		for( int i = 1, x; i <= n; i++ ) scanf( "%d", &x ), s1[i] = s1[i-1] + x;
		for( int i = 1; i <= n; i++ )
			for( int l = 1; l <= k; l++ ){
				f[i][l] = f[i-1][l];
				for( int j = 0; j < i; j++ )
					f[i][l] = max( f[j][l-1] + s1[i] - s1[j], f[i][l] );
			}
		printf( "%d\n", f[n][k] );
	}else{
		for( int i = 1, x, y; i <= n; i++ )
			scanf( "%d%d", &x, &y ), s1[i] = s1[i-1] + x, s2[i] = s2[i-1] + y;
		for( int l = 1; l <= k; l++ )
			for( int i = 1; i <= n; i++ )
				for( int j = 1; j <= n; j++ ){
					dp[i][j][l] = max( dp[i-1][j][l], dp[i][j-1][l] );
					for( int p = 0; p < i; p++ )
						dp[i][j][l] = max( dp[p][j][l-1] + s1[i] - s1[p], dp[i][j][l] );
					for( int p = 0; p < j; p++ )
						dp[i][j][l] = max( dp[i][p][l-1] + s2[j] - s2[p], dp[i][j][l] );
					if( i == j ){
						for( int p = 0; p < i; p++ )
							dp[i][j][l] = max( dp[i][j][l],
							dp[p][p][l-1] + s1[i] - s1[p] + s2[i] - s2[p] );
					}
				}
		printf( "%d\n", dp[n][n][k] );
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章