题目大意:切割图形,给你一个非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; }