Matrix Swapping II
Total Submission(s): 1210 Accepted Submission(s): 804
We can swap any two columns any times, and we are to make the goodness of the matrix as large as possible.
看了別人的纔會,要我看怎麼看都是枚舉出所有情況,求最大矩陣。
注意要連續才行。我看成行互換去了。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; }