• E


    题目大意:切割图形,给你一个非0即1的矩阵,将它切割成多个长方形,使每个小长方形中1的个数不得多于k个,切割的规则,要么切一整行,要么是一整列、

     题解: 二进制枚举。

    注意行数最大才是10。用二进制枚举切割某一行,然后在枚举每一列是否需要切割。时间复杂度O(2^h*m)

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1E3+7;
    const int INF=1e9+7;
    int mp[N][N];
    int arr[N];
    int n,m,k;
    vector<int>ve;
    int cal(int x,int y,int j){//用来计算第从x到y行第j列的值。
        int sum=0;
        for(int i=x;i<=y;i++)
            sum+=mp[i][j];
        return sum;
    }
    int check(){
        int c=ve.size(),sum=0;
        for(int k1=1;k1<c;k1++) arr[k1]=0;
        bool flag=0;
        for(int j=1;j<=m;j++){
            for(int k1=1;k1<c;k1++){
                arr[k1]+=cal(ve[k1-1]+1,ve[k1],j);
                if(arr[k1]>k){
                    sum++;
                    flag=1;
                    break;
                }
            }
            if(!flag) continue ;
            flag=0;
            for(int k1=1;k1<c;k1++){
                arr[k1]=cal(ve[k1-1]+1,ve[k1],j);
                if(arr[k1]>k) return INF;
            }
        }
        return sum;
    }
    int main(){
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                char x;
                cin>>x;
                if(x=='1') mp[i][j]=1;
                else mp[i][j]=0;
            }
        }
        int c=(1<<(n-1))-1;
        int ans=INF;
        for(int i=0;i<=c;i++){
            ve.push_back(0);
            for(int j=0;j<n-1;j++)
                if((1<<j)&i) ve.push_back(j+1);
            ve.push_back(n);
            int x=ve.size();
            ans=min(ans,x-2+check());
            ve.clear();
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    excel表中的一列,如何去除重复项
    Notepad++ 列操作
    mysql 登陆其它服务器
    贪心算法处理背包问题
    分治法处理排序问题
    回溯法_皇后问题
    动态规划算法的java实现
    人事管理系统
    java复习笔记
    核心动画-翻页效果的实现
  • 原文地址:https://www.cnblogs.com/Accepting/p/12554854.html
Copyright © 2020-2023  润新知