Codeforces Round #221 (Div. 2) D

有点郁闷的题目,给了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();
	}
}
时间: 2024-12-29 06:06:07

Codeforces Round #221 (Div. 2) D的相关文章

Codeforces Round #221 (Div. 2) D. Maximum Submatrix 2 (思维题)

题目地址:codeforces 221 D 这场是人生中做的第一场CF中的D题.(当时只做出来了A题..)过年之际回顾了一下,就顺便看了几道D题.现在做CF的D题在比赛时还是做不出来.但是赛后往往都可以自己做出来.据说D题能在比赛中稳出的话就可以区域赛银了.于是争取以后CF能稳出4道题吧. 这道题刚开始不该看标签的..给的是DP..于是就一直朝着DP方向想.但是感觉不像是DP.就换了个思路,就做出来了. 大体方法是先预处理出每一行中每个数向左延伸最长的连续1的个数.然后对每一行的进行排序(我这里

Codeforces Round #221 (Div. 1) B. Maximum Submatrix 2 dp排序

B. Maximum Submatrix 2 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/375/B Description You are given a matrix consisting of digits zero and one, its size is n × m. You are allowed to rearrange its rows. What is

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #633 (Div. 2)

Codeforces Round #633(Div.2) \(A.Filling\ Diamonds\) 答案就是构成的六边形数量+1 //#pragma GCC optimize("O3") //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace std; function<void(void)> __

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除