soj 12646. ORCHARD

12646. ORCHARD

Constraints

Time Limit: 3 secs, Memory Limit: 256 MB

Description

 

Alex and Bert are brothers who had been working for many years in a big orchard of their uncle where they planted trees. The orchard is arranged as an array of size n by m of trees. Alex had been planting apple trees and Bert had been planting banana trees; however, the brothers were not systematic and so apple trees stand among banana trees and vice versa. Each of them has planted at least one tree.

When coming near to retirement, the uncle decided to officially transfer the ownership of the trees to the brothers. The uncle informed the brothers that he will first pass the orchard to Alex. Next, Alex and Bert can cut out a rectangular area from the orchard, and the ownerships of all trees in the rectangular area are to be transferred to Bert. All further adjustments of the splitting had to be done with a lawyer.

Alex would like to keep all apple trees and Bert would like to keep all banana trees, but do not want to replant any tree. When they talked to a lawyer, the lawyer informed them that the ownership of a tree can be transferred from one owner to another, but the lawyer would charge $1 to transfer the ownership of a tree. Therefore the brothers try to place the starting rectangle such that the legal fees are as low as possible.

The following figures show three examples, where 0 and 1 indicates an apple and banana tree respectively.

In the first example, the best way is to cut out the fourth column and to assign it to Bert, as indicated by the rectangular outline. Afterwards, there are two trees that are out of place, and their ownerships have to be transferred – one banana tree from Alex to Bert and one apple tree from Bert to Alex. Hence, the fees are $2.

In the second example, the best way is to cut out trees that are not at the border of the field and then to transfer the ownership of six trees. The fees are $6.

In the third example, the best way is to cut out the rectangle consisting of 3 banana trees, and then to transfer the ownership of the rightmost banana tree to Bert. The fee is $1. Note that there is an alternative way that costs $1 as well.

 

Input

 

The first line of the input are the two positive numbers n and m (1<=n<=150, 2<=n*m<=750000) indicating the orchard’s size. Then follow n lines each consisting of m numbers, where 0 represents an apple tree and 1 represents a banana tree.

 

Output

 

You program must write to the standard output a number, which is the smallest fee required.

 

Sample Input

5 7
0 0 1 0 0 1 0
0 1 1 1 1 1 0
0 1 1 0 0 1 0
0 1 1 1 1 1 0
0 0 1 0 0 1 0

Sample Output

6

Problem Source

2014年每周一赛第十三场

题意: 给出n*m的01矩阵,你选出一个x*y的矩阵,f = x*y里面白点的个数 +不在x*y 里面黑点的个数

我们求的是 f最小

思路 : f=a+len-b ,a是x*y里面0点个数,b 是x*y里面1点的个数

只要 求a-b最小就可以了

我们枚举选出的矩阵的行,然后O(m)求答案

这个大概想求最大连续和一样 ,如果前面的对后面的有贡献,就加上

没有就置 0 

// Problem#: 12646
// Submission#: 3287759
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <vector>
#define LL long long
#define maxn 1000010
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;

int sum[750010];
vector<int>a[160];
int ans1,ans2;

void getans(int L,int m)
{
    int sum1=0,sum2=0;
    for(int i = 1 ; i <= m ;i++)
    {
        sum2 += sum[i] ;
        sum1 += L-sum[i] ;
        if(sum1>=sum2)
        {
            sum1=sum2=0;
            continue ;
        }
        if(sum2-sum1>ans2-ans1)
        {
            ans1=sum1;
            ans2=sum2;
        }
    }
}
int main()
{
    int i,n,m,j,Max;
    int len ,k;
    while(scanf("%d%d",&n,&m) != EOF)
    {
        len=0;
        for( i = 1 ; i <= n ;i++){
          a[i].clear();
          a[i].push_back(1);
          for( j =1 ; j <= m;j++){
              scanf("%d",&k) ;
              if(k==1)len++;
              a[i].push_back(k);
          }
        }
        ans1=ans2=0;
        for( i = 1 ; i <= n ;i++)
        {
            for(k = 1 ;k <= m;k++)sum[k]=0;
            for( j = i ; j <= n ;j++)
            {
                for(k = 1 ;k <= m;k++)
                    sum[k] += a[j][k];
                getans(j-i+1,m) ;
            }
        }
        //cout<<ans1<<" " <<ans2<<endl;
        cout<<ans1+len-ans2<<endl;
    }
    return 0 ;

}                                 
View Code

 

posted @ 2014-11-29 13:00  _log__  阅读(200)  评论(0编辑  收藏  举报