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 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.
 

Source
 

Recommend
gaojie   |   We have carefully selected several similar problems for you:  2870 2577 1505 1421 2571
  看了別人的纔會,要我看怎麼看都是枚舉出所有情況,求最大矩陣。
注意要連續才行。我看成行互換去了。OTL

題意:

給你一個矩陣,裏面的數字只有0和1兩種,其中,列可以任意移動。問如何移動可以使某個子矩陣中元素全部是1,求出這個最大子矩陣的面積。

解題思路:

枚舉所有的尾行,然後對於每個尾行,記錄到這行爲止每列連續的1的個數,爲了形象起見,我們可以把每列看做寬度爲1,連續個數看做它的高度。

然後問題就可以看做在一些高度可能爲0的相鄰矩形中找到最大矩形,即最大長方形那道題,如下圖。


此題的另外一個條件是可以將列任意移動,我們肯定要儘量將高度大的放在一起,所以,我們可以將高度從大到小排序,然後有h[i-1]>=h[i],

即如果將1,2…i個矩形連在一起,它的高應該是h[i],所以面積顯然是h[i] * i。

然後我們就枚舉i從1到n,就可以解決這個問題了。

代碼:763MS
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
using namespace std;
#define M 2000
#define max(a,b) (a>b?a:b)
bool cmp(int x,int y){
return x>y;
}
char map[M][M];
int main()
{
    int i,j,n,m,Max,vis[M],dis[M];
    while(cin>>n>>m)
   {   Max=0;
       memset(dis,0,sizeof(0));
       for(i=1;i<=n;i++)
      {
       for(j=1;j<=m;j++)
      {
        cin>>map[i][j];
        if(map[i][j]=='1') dis[j]++;    //如果是一就表示高度爲之前的高度+1。
        else dis[j]=0                   //如果該點維一,那麼就不連續,且當前高度爲零。
        vis[j]=dis[j];                  //這裏要用到另一個數組,因爲後面要從大到小排序,dis不能動,因爲之後還有用的。
      }
      sort(vis+1,vis+1+m,cmp);          //用意前面以講明。
      for(j=1;j<=m;j++) 
          if(vis[j]*j>Max)  Max=vis[j]*j;  //vis還只是高度。
      }
     cout<<Max<<endl;
   }
    return 0;
}

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