1. 程式人生 > >Codeforces Round #221 (Div. 2) D

Codeforces Round #221 (Div. 2) D

cpp 位置 input memset ont code init cal 矩形

有點郁悶的題目,給了2000ms,可是n,m的範圍已經是5000了。5000 * 5000一般在別的OJ已經是超了2000ms,一開始不敢敲。看了下別人有n*m的潛逃循環,原來CF的機子如此的強大,一開始題意沒看清錯了,原來隨意行能夠交換,列不行

那就先dp出 每一行的 每個位置包含它本身以及前面的連續出現1的長度。然後再對列進行處理。由於列是不能變的。所以相應列是固定的,那麽就對列枚舉,然後由於行能夠交換。所以詳細哪一列在哪一行能夠變化。就把前面dp出的最大的放在最後面,意思就是呈現一個倒著放的梯形 當然也有可能是矩形,在中求一個面積最大的矩形就可以,



int n,m;

char mp[5000 + 55][5000 + 55];

int dp[5000 + 55][5000 + 55];

void init() {
	memset(mp,0,sizeof(mp));
	memset(dp,0,sizeof(dp));
}

bool input() {
	while(scanf("%d %d",&n,&m) == 2) {
		for(int i=1;i<=n;i++) 
			scanf("%s",mp[i] + 1);
		return false;
	}
	return true;
}

void cal() {
	for(int i=1;i<=n;i++) {
		dp[i][0] = 0;
		for(int j=1;j<=m;j++)
			dp[i][j] =  mp[i][j] == ‘1‘?

dp[i][j - 1] + 1:0; } int ans = 0; for(int j=1;j<=m;j++) { int tmp[5000 + 55]; for(int i=1;i<=n;i++)tmp[i] = dp[i][j]; sort(tmp + 1,tmp + n + 1); for(int i=1;i<=n;i++)ans =max(ans,tmp[i] * (n - i + 1)); } cout<<ans<<endl; } void output() { } int main () { while(true) { init(); if(input())return 0; cal(); output(); } }




Codeforces Round #221 (Div. 2) D