太蠢了,,,因为初始化大数据没过,丢了10分,纪念一下这个错误
大概思路:先求出让损失值最小的排列,由已生成的这些排列,通过更改某一个位置的值,生成下一个最优解,迭代最多生成m+1个最优解即可,遍历求出没有被禁的最优解即可
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<vector> #include<string.h> #include<cstring> #include<algorithm> #include<set> #include<map> #include<fstream> #include<cstdlib> #include<ctime> #include<list> #include<climits> #include<bitset> using namespace std; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout); #define left asfdasdasdfasdfsdfasfsdfasfdas1 #define tan asfdasdasdfasdfasfdfasfsdfasfdas typedef long long ll; typedef unsigned int un; const int desll[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; const ll mod=1e9+7; const int maxn=4e2+7; const int maxm=1e6+7; const double eps=1e-4; int m,n,p; int ar[maxn]; char c[maxn]; set<pair<int,string> > se; set<string> seMid; char cha(char c) { return c=='1'?'0':'1'; } int main() { fopen int t,fir=0;scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&m,&p); memset(ar,0,sizeof(ar)); seMid.clear(); se.clear(); for(int i=0;i<n;i++){ scanf("%s",c); for(int j=0;j<p;j++){ if(c[j]=='0')ar[j]++; } } for(int i=0;i<m;i++){ scanf("%s",c); seMid.insert(string(c)); } string str(p,'1'); int mid=0; for(int i=0;i<p;i++){ if(ar[i]>n/2){ str[i]='0'; ar[i]=n-ar[i]; } mid+=ar[i]; } se.insert(make_pair(mid,string(str))); int ans=0; while((int)se.size()<=m){ int mn=p*n; string ss; for(set<pair<int,string>>::iterator au = se.begin();au!=se.end();au++){ mid = au->first; string sMid = au->second; if(mid>mn)break; for(int i=0;i<p;i++){ if(sMid[i]==str[i] && mn>mid+n-2*ar[i]){ sMid[i] = cha(sMid[i]); if(se.count(make_pair(mid+n-2*ar[i],sMid))==0){ mn=mid+n-2*ar[i]; ss=sMid; } sMid[i] = cha(sMid[i]); } } } se.insert(make_pair(mn,ss)); if(seMid.count(ss)==0)break; } set<pair<int,string>>::iterator au=se.begin(); for(;au!=se.end();au++){ string sMid = au->second; if(seMid.count(sMid)==0){ ans=au->first; break; } } printf("Case #%d: %d ",++fir,ans); } return 0; }