Codeforces Round #221 (Div. 1) B:http://codeforces.com/problemset/problem/375/B
题意:给你一个n*m的0,1矩阵,你可以交换一些行,求一个最大子矩阵的面积,这个子矩阵全部包含1.
题解:看标签是数据结构,怎么想,也不知道用数据结构怎么搞。最后想到是求面积,面积不就是l*d,只要确定了了l和d,面积就出来了,于是我想到了枚举l和d。这里要先处理出来一些东西,dp[j][i]表示(i,j)的右边的有多少个连续的1,包括(i,j),可以这么想,矩阵的左边一定出现在那一列,所以可以枚举列,对于固定左边来说,也就是起点固定了,那么狠容易想到,,要把连续1多的放在一起,所以要对该列进行排个序,然后就可以开始枚举,从上到下,因为最上面的是最短的,所以下面构成的面积才是我们想要的。得到最大的面积。表述不是很清晰,还是看代码吧。题解说用基数排序,但是我用了基数排序,发现比类库的排序要慢,也许是数据小的原因吧。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=5004; 7 int n,m,r[N][N]; 8 char mp[N][N]; 9 bool temp[N]; 10 /*int counts[N],tmp[N]; 11 int maxbit(int x){ 12 int d=1; 13 for(int i=1;i<=n;i++){ 14 int c=1; 15 int p=r[x][i]; 16 while(p/10){ 17 p=p/10; 18 c++; 19 } 20 if(c>d) 21 d=c; 22 } 23 return d; 24 } 25 void RadixSort(int x){ 26 int d=maxbit(x); 27 int rr=1; 28 for(int i=0;i<d;i++){ 29 for(int j=0;j<10;j++) 30 counts[j]=0; 31 for(int j=1;j<=n;j++) { 32 int k=r[x][j]/rr; 33 int q=k%10; 34 counts[q]++; 35 } 36 for(int j=1;j<10;j++){ 37 counts[j]+=counts[j-1]; 38 } 39 for(int j=n;j>=1;j--) 40 { 41 int p=r[x][j]/rr; 42 int s=p%10; 43 tmp[counts[s]-1]=r[x][j]; 44 counts[s]--; 45 } 46 for(int j=0;j<n;j++){ 47 r[x][j+1]=tmp[j]; 48 } 49 rr=rr*10; 50 } 51 }*/ 52 int main(){ 53 while(~scanf("%d%d",&n,&m)){ 54 memset(r,0,sizeof(r)); 55 for(int i=1;i<=n;i++) 56 scanf("%s",mp[i]+1); 57 for(int i=1;i<=n;i++){ 58 int temp=0; 59 for(int j=m;j>=1;j--){ 60 if(mp[i][j]=='0'){ 61 temp=0; 62 } 63 else 64 temp++; 65 r[j][i]=temp; 66 } 67 } 68 int ans=0; 69 for(int i=1;i<=m;i++){ 70 //RadixSort(i); 71 sort(r[i]+1,r[i]+n+1); 72 for(int j=1;j<=n;j++){ 73 ans=max(ans,r[i][j]*(n-j+1)); 74 } 75 } 76 printf("%d ",ans); 77 } 78 }