TopCoderOpen Round 1A 1000点問題

解法

枝刈りしつつ全探索する.

実装(C++)

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;

typedef long long int lli;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=(x);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
bool comp(const string &a,const string &b){
	int _a=0,_b=0;
	REP(i,a.size()){
		if(a[i]=='Y')_a++;
		if(b[i]=='Y')_b++;
	}
	return _a>_b;
}
int C,R;
int answer=51;
vector<int> remain_column;
vector<bool> used_column;
vector<bool> used;
string s;
vector<string> matrix;
void doIt(const string &a){
	for(int i=0;i<(int)a.size();i++){
		if((s[i]=='Y')^(a[i]=='Y')){
			s[i]='Y';
		}else{
			s[i]='N';
		}
	}
}
void dfs(int count){
	int tar=-1,minimum=99;
	vector<int> cr;
	//列について一番小さいものを求める
	for(int i=0;i<C;i++){
		if(remain_column[i]==0){
			if(s[i]=='Y')return;
			used_column[i]=true;
			cr.push_back(i);
		}else{
			if(minimum>remain_column[i]){
				minimum=remain_column[i];
				tar=i;
			}
		}
	}
	if(tar==-1){
		answer=min(answer,count);
		REP(i,cr.size())used_column[cr[i]]=false;
		return;
	}
	//含まれるものを確定する
	vector<int> cc;
	REP(i,R){
		if(used[i])continue;
		if(matrix[i][tar]=='Y'){
			cc.push_back(i);
			used[i]=true;
			REP(j,C){
				if(matrix[i][j]=='Y')remain_column[j]-=1;
			}
		}
	}
	if(s[tar]=='Y'){
		REP(i,cc.size()){
			doIt(matrix[cc[i]]);
			dfs(count+1);
			doIt(matrix[cc[i]]);
		}
	}else{
		dfs(count);
		if(cc.size()>1){
			REP(i,cc.size()){
				doIt(matrix[cc[i]]);
			}
			dfs(count+2);
			REP(i,cc.size()){
				doIt(matrix[cc[i]]);
			}
		}
	}

	REP(i,cr.size())used_column[cr[i]]=false;
	REP(k,cc.size()){
		int i=cc[k];
		used[i]=false;
		REP(j,C){
			if(matrix[i][j]=='Y')remain_column[j]+=1;
		}
	}
	return;
}
class EllysLights {
public: int getMinimum(string initial, vector<string> switches) {
	sort(switches.begin(),switches.end());
	switches.erase(unique(switches.begin(),switches.end()),switches.end());
	stable_sort(switches.begin(),switches.end(),comp);
	cout<<initial<<endl;
	cout<<"---"<<endl;
	REP(i,switches.size()){
			cout<<switches[i]<<endl;
	}
	remain_column=vector<int>(initial.size());
	C=initial.size();
	R=switches.size();
	for(int i=0;i<C;i++){
		for(int j=0;j<R;j++){
			if(switches[j][i]=='Y')remain_column[i]++;
		}
	}
	used=vector<bool>(R,false);
	used_column=vector<bool>(C,false);
	answer=51;
	matrix=switches;
	s=initial;
	dfs(0);
	if(answer>50)answer=-1;
	return answer;
}
};