码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 425B Sereja and Table(状态压缩,也可以数组模拟)

时间:2014-08-06 14:33:01      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

题目

 

给出一个n*m的01矩阵, 让你最多改变k个里面的值(0变1,1变0), 使得0、1的连通分量是矩阵。输出最少步数

1 ≤ n, m ≤ 100; 1 ≤ k ≤ 10

 

题解:

如果01连通分量是矩形,

那么矩形一定是这样的:

0101010

1010101

0101010

1010101

(上面的01代表子矩阵块)。

也就是每一行要么是相同,要么是相反的。

 

如果n>k, 肯定有一行是不能改变的,那么枚举这一行,然后其余的要么变相同,要么变相反,看最少的步数。

如果n<k ,那么可以枚举第一列的状态(2^k), 然后其余列变成和第一列相同或者相反。

 

以上引用自:http://www.cnblogs.com/kuangbin/p/3702113.html

 

//我不知道我这种模拟算不算是状态压缩

bubuko.com,布布扣
#include <cstdio>
#include<iostream>
#include <cstring>
#include <algorithm>
#include<vector>
using namespace std;
int k,n,m;
int a[110][110];

int min(int x,int y)
{
    if(x<y)return x;
    return y;
}

int meijuh()
{
    int minn=210000000;
    for(int i=0;i<k+1;i++)
    {
        int ans=0;
        for(int ii=0;ii<n;ii++)
        {
            if(i!=ii)
            {
                int sa=0,di=0;
                for(int j=0;j<m;j++)
                {
                    if(a[i][j]==a[ii][j])
                        sa++;
                    else 
                        di++;
                }
                ans+=min(sa,di);
            }
        }
        minn=min(minn,ans);
    }
    return minn;
}
int meijul()
{
    int er[2048][11];
    for(int i=0;i<2048;i++)er[i][0]=i&1;
    for(int i=0;i<1024;i++)for(int j=0;j<2;j++)er[i*2+j][1]=i&1;
    for(int i=0;i<512;i++)for(int j=0;j<4;j++)er[i*4+j][2]=i&1;
    for(int i=0;i<256;i++)for(int j=0;j<8;j++)er[i*8+j][3]=i&1;
    for(int i=0;i<128;i++)for(int j=0;j<16;j++)er[i*16+j][4]=i&1;
    for(int i=0;i<64;i++)for(int j=0;j<32;j++)er[i*32+j][5]=i&1;
    for(int i=0;i<32;i++)for(int j=0;j<64;j++)er[i*64+j][6]=i&1;
    for(int i=0;i<16;i++)for(int j=0;j<128;j++)er[i*128+j][7]=i&1;
    for(int i=0;i<8;i++)for(int j=0;j<256;j++)er[i*256+j][8]=i&1;
    for(int i=0;i<4;i++)for(int j=0;j<512;j++)er[i*512+j][9]=i&1;
    for(int i=0;i<2;i++)for(int j=0;j<1024;j++)er[i*1024+j][10]=i&1;
    
    int minn=210000000;
    for(int i=0;i<(1<<n);i++)
    {
        int ans=0;
        for(int j=0;j<m;j++)
        {
            int sa=0,di=0;
            for(int ii=0;ii<n;ii++)
            {
                if(er[i][ii]==a[ii][j])
                    sa++;
                else di++;
            }
            ans=ans+min(sa,di);
        }
        minn=min(minn,ans);
    }
    return minn;
}

int main() {

    cin >>n>>m>>k;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin >>a[i][j];
    int minn=210000000;
    if(n>k)
    {
        minn = meijuh();
    }
    else 
    {
        minn=meijul();
    }
    if(minn<=k)
        cout << minn<<endl;
    else 
        cout <<-1<<endl;
    return 0;
}
View Code

 

codeforces 425B Sereja and Table(状态压缩,也可以数组模拟),布布扣,bubuko.com

codeforces 425B Sereja and Table(状态压缩,也可以数组模拟)

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/laiba2004/p/3894304.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!