Matrix Swapping II

本文探讨了一种矩阵操作问题,目标是在矩阵中通过任意列交换来最大化矩阵的优良度。介绍了通过排序和贪心策略优化算法的过程,并提供了具体的代码实现。重点在于通过排序和贪心思想解决矩阵优化问题,代码实现简洁高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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 times, and we are to make the goodness of the matrix as large as possible.
 

Input

There are several test cases in the input. The first line of each test case contains two integers N and M (1 ≤ N,M ≤ 1000). Then N lines follow, each contains M numbers (0 or 1), indicating the N * M matrix
 

Output

Output one line for each test case, indicating the maximum possible goodness.
 

Sample Input

3 4
1011
1001
0001
3 4
1010
1001
0001 

Sample Output

4
2
Note: Huge Input, scanf() is recommended. 

这道题 最后的思路和上篇一样,只是加了次排序,因为可以任意交换两列(具体解法看上篇思路 )
然后贪心的思路,我们可以让它有高度的 高度高的尽量在前面或者后面
然后处理完就是和上题一样的代码了
注意输入 用%1d每次只读入一个数字,不用字符数组读入 方便许多
代码如下:
//
// Create by 神舟 on 2015-02-13
//

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cctype>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <set>
#include <vector>
using namespace std;

#define CLR(x) memset(x,0,sizeof x)
#define ll long long
#define inf 0x3f3f3f3f
const int maxn=1e3+5;
const int MOD=5e5+5;
int sum[maxn][maxn];
int l[maxn],r[maxn];
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);

int n,m,num;
while(scanf("%d%d",&n,&m)!=EOF){
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
            scanf("%1d",&num);
            if(num) sum[i][j]=sum[i-1][j]+num;
            else sum[i][j]=0;
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            sort(sum[i]+1,sum[i]+m+1);
            for(int j=1;j<=m;j++){
                l[j]=j;
                while(l[j]>1&&sum[i][l[j]-1]>=sum[i][j]) l[j]=l[l[j]-1];
            }
            for(int j=m;j>0;j--){
                r[j]=m;
                while(r[j]<m&&sum[i][j]<=sum[i][r[j]+1]) r[j]=r[r[j]+1];
            }
            for(int j=1;j<=m;j++) ans=max(ans,sum[i][j]*(1+r[j]-l[j]));//dp思想应用具体看前一篇
        }
        printf("%d\n",ans);
}
return 0;
}
空间比上篇优化了,其实还可以在优化,把sum优化成一维数组,在处理sum 的同时就进行计算每行最大值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值