hdu 2830 Matrix Swapping II dp 动态规划

//这题和之前的2870题意相似,不过多了可以任意交换两列的功能
//先开始没看见能交换两列。。。结果裸的样例都没过,最后想了想//任意交换两列,那我们就可以直接对第i行第j列得到的cnt[i][j]
//这一行惊醒排序就可以了,其中cnt[i][j]表示前i行第j列有多少
//个相同的1,进行降序排序得到a[j],那么a[j]*j的最大值就是我
//们所要的答案,因为j前面的肯定是高于j的。
//注释部分是我之前的2870的裸的代码,具体可以看我的博客dp46道专题
 //哎,继续练吧。。。

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#define ceil(a,b) (((a)+(b)-1)/(b))
#define endl '\n'
#define gcd __gcd
#define highBit(x) (1ULL<<(63-__builtin_clzll(x)))
#define popCount __builtin_popcountll
typedef long long ll;
using namespace std;
const int MOD = 1000000007;
const long double PI = acos(-1.L);

template<class T> inline T lcm(const T& a, const T& b) { return a/gcd(a, b)*b; }
template<class T> inline T lowBit(const T& x) { return x&-x; }
template<class T> inline T maximize(T& a, const T& b) { return a=a<b?b:a; }
template<class T> inline T minimize(T& a, const T& b) { return a=a<b?a:b; }

const int maxn = 1024;
char mp[maxn][maxn];
int cnt[maxn][maxn];
int l[maxn];
int r[maxn];
int n,m;
int ans;
int a[maxn];
bool cmp(int a,int b){
	return a>b;
}

void init(){
	for (int i=1;i<=n;i++)
		scanf("%s",mp[i]+1);
	//for (int i=1;i<=n;i++)
	//	printf("%s\n",mp[i]+1);
	memset(cnt,0,sizeof(cnt));
	ans = 0;
}

void solve(){
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			l[j] = r[j] = j;
			if (mp[i][j]=='1')
				cnt[i][j] = cnt[i-1][j]+1;
			else cnt[i][j] = 0;
		}
		for (int j=1;j<=m;j++)
			a[j] = cnt[i][j];
		sort(a+1,a+m+1,cmp);
		//for (int j=2;j<=m;j++){
		//	if (!cnt[i][j])	continue;
		//	while(cnt[i][l[j]-1]>=cnt[i][j])
		//		l[j] = l[l[j]-1];
		//}

		//for (int j=m-1;j>=1;j--){
		//	if (!cnt[i][j])	continue;
		//	while(cnt[i][r[j]+1]>=cnt[i][j])
		//		r[j] = r[r[j]+1];
		//}

		for (int j=1;j<=m;j++){
			//if (!cnt[i][j])	continue;
			ans = max(ans,a[j]*j);
		}
	}
	printf("%d\n",ans);
}

int main() {
    //freopen("G:\\Code\\1.txt","r",stdin);
	while(scanf("%d%d",&n,&m)!=EOF){
		init();
		solve();
	}
	return 0;
}

时间: 2024-08-11 23:32:42

hdu 2830 Matrix Swapping II dp 动态规划的相关文章

HDU 2830 Matrix Swapping II (DP,最大全1矩阵)

题意  给你一个n*m矩阵  每列都可以随便交换位置   求最优交换后最大的全1子矩阵 又是HDU 1505 1506的变种  但这个更容易了  因为每列都可以交换位置了   那么这一行中所有比i高的都可以与i相邻了  只需要统计这一行有多少个比i高就行了   可以在算出每一行后  把高度大的放前面去  用num[i]记录排序后的列原来的数  这样就有j列比h[i][num[j]]高了  最后的答案也就是max(j*h[i][num[j]]) #include<cstdio> #include

HDU 2830 Matrix Swapping II

给一个矩阵,依然是求满足条件的最大子矩阵 不过题目中说任意两列可以交换,这是对题目的简化 求出h数组以后直接排序,然后找出(col-j)*h[j]的最大值即可(这里的j是从0开始) 因为排序会影响到h数组下一行的求解,所以将h数组中的元素复制到temp数组中去,再排序 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algori

HDU 2830 Matrix Swapping II (最大完全子矩阵之可移动列)

Matrix Swapping II Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1210    Accepted Submission(s): 804 Problem Description Given an N * M matrix with each entry equal to 0 or 1. We can find som

HDU 2830 Matrix Swapping II (预处理的线性dp)

Matrix Swapping II Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1430    Accepted Submission(s): 950 Problem Description Given an N * M matrix with each entry equal to 0 or 1. We can find som

HDu 2830 Matrix Swapping II(dp)

Problem Description Given an N * M matrix with each entry equal to 0 or 1. We can find some rectangles in the matrix whose entries are all 1, and we define the maximum area of such rectangle as this matrix's goodness. We can swap any two columns any

hdu 2830 Matrix Swapping II(额,,排序?)

题意: N*M的矩阵,每个格中不是0就是1. 可以任意交换某两列.最后得到一个新矩阵. 问可以得到的最大的子矩形面积是多少(这个子矩形必须全是1). 思路: 先统计,a[i][j]记录从第i行第j列格往上连续的0的个数. 枚举每一行作为答案子矩阵的底, 然后将这一行的a[i][j]从大到小排序,扫一遍计算. 看代码. 代码: int n,m; char temps[1005][1005]; int a[1005][1005]; int ts[1005]; bool cmp(int a,int b

hdu 2830 Matrix Swapping II(hdu1505的加强版)

#include<cstdio> #include<cstring> #include<algorithm> #define N 1005 using namespace std; const int INF=1<<30; char mat[N][N]; int a[N][N]; int L[N],R[N]; int main() { int m,n; memset(a,0,sizeof(0)); while(scanf("%d%d",&

HDU 2830 Matrix Swapping II(最大完全子矩阵之可移动列)

/* 题意: 给你一个矩阵,里面的数字只有0和1两种,其中,列可以任意移动.问如何移动可以使某个子矩阵中元素全部是1,求出这个最大子矩阵的面积. 对每一行进行处理然后再叠加,到每一行用num[i]记下到这一行有多少个1 例如: 1 0 1 1 num[i]的记录就是: 1 0 1 1 1 0 0 1 2 0 0 2 0 0 0 1 0 0 0 3 然后对num[i]从大到小排一下,求出读取到当前行能够得到的最大面积. 也就是最右边放着最多的1,依次类推.那么当前最大的面积就是 MAX(max,n

【HDOJ】2830 Matrix Swapping II

简单DP. 1 /* 2830 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <algorithm> 10 #include <cstdio> 11 #