29d1d6cd26 2012-07-21 kinaba: #include <iostream> 29d1d6cd26 2012-07-21 kinaba: #include <sstream> 29d1d6cd26 2012-07-21 kinaba: #include <iomanip> 29d1d6cd26 2012-07-21 kinaba: #include <vector> 29d1d6cd26 2012-07-21 kinaba: #include <string> 29d1d6cd26 2012-07-21 kinaba: #include <map> 29d1d6cd26 2012-07-21 kinaba: #include <set> 29d1d6cd26 2012-07-21 kinaba: #include <algorithm> 29d1d6cd26 2012-07-21 kinaba: #include <numeric> 29d1d6cd26 2012-07-21 kinaba: #include <iterator> 29d1d6cd26 2012-07-21 kinaba: #include <functional> 29d1d6cd26 2012-07-21 kinaba: #include <complex> 29d1d6cd26 2012-07-21 kinaba: #include <queue> 29d1d6cd26 2012-07-21 kinaba: #include <stack> 29d1d6cd26 2012-07-21 kinaba: #include <cmath> 29d1d6cd26 2012-07-21 kinaba: #include <cassert> 29d1d6cd26 2012-07-21 kinaba: using namespace std; 29d1d6cd26 2012-07-21 kinaba: typedef long long LL; 29d1d6cd26 2012-07-21 kinaba: typedef long double LD; 29d1d6cd26 2012-07-21 kinaba: typedef complex<LD> CMP; 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: class MagicalHats { public: 29d1d6cd26 2012-07-21 kinaba: int NC, NH, H, W, NG; 29d1d6cd26 2012-07-21 kinaba: vector<int> gain; 29d1d6cd26 2012-07-21 kinaba: vector< pair<int,int> > hats; 29d1d6cd26 2012-07-21 kinaba: vector<int> tate_base, yoko_base; 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: int findMaximumReward(vector <string> board, vector <int> coins, int numGuesses) 29d1d6cd26 2012-07-21 kinaba: { 29d1d6cd26 2012-07-21 kinaba: NC = coins.size(); 29d1d6cd26 2012-07-21 kinaba: sort(coins.begin(), coins.end()); 29d1d6cd26 2012-07-21 kinaba: gain.assign(NC+1, 0); 29d1d6cd26 2012-07-21 kinaba: partial_sum(coins.begin(), coins.end(), gain.begin()+1); 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: H = board.size(); 29d1d6cd26 2012-07-21 kinaba: W = board[0].size(); 29d1d6cd26 2012-07-21 kinaba: hats.clear(); 29d1d6cd26 2012-07-21 kinaba: tate_base.resize(W); 29d1d6cd26 2012-07-21 kinaba: yoko_base.resize(H); 29d1d6cd26 2012-07-21 kinaba: for(int y=0; y<H; ++y) 29d1d6cd26 2012-07-21 kinaba: for(int x=0; x<W; ++x) 29d1d6cd26 2012-07-21 kinaba: if(board[y][x] == 'H') { 29d1d6cd26 2012-07-21 kinaba: hats.push_back( make_pair(y,x) ); 29d1d6cd26 2012-07-21 kinaba: tate_base[x]++; 29d1d6cd26 2012-07-21 kinaba: yoko_base[y]++; 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: NH = hats.size(); 29d1d6cd26 2012-07-21 kinaba: NG = numGuesses; 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: int m = 0; 29d1d6cd26 2012-07-21 kinaba: for(int i=0; i<NH; ++i) 29d1d6cd26 2012-07-21 kinaba: m = m*3 + 2; 29d1d6cd26 2012-07-21 kinaba: p_memo.resize(m+1); 29d1d6cd26 2012-07-21 kinaba: p_memo_set.resize(m+1); 29d1d6cd26 2012-07-21 kinaba: b_memo.resize(m+1); 29d1d6cd26 2012-07-21 kinaba: b_memo_set.resize(m+1); 29d1d6cd26 2012-07-21 kinaba: return is_possible(m) ? gain[best_num(m, NG)] : -1; 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: vector<bool> p_memo; 29d1d6cd26 2012-07-21 kinaba: vector<bool> p_memo_set; 29d1d6cd26 2012-07-21 kinaba: bool is_possible(int state) 29d1d6cd26 2012-07-21 kinaba: { 29d1d6cd26 2012-07-21 kinaba: if(p_memo_set[state]) 29d1d6cd26 2012-07-21 kinaba: return p_memo[state]; 29d1d6cd26 2012-07-21 kinaba: p_memo_set[state] = true; 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: vector<int> yoko = yoko_base, tate = tate_base, next; 29d1d6cd26 2012-07-21 kinaba: int cnt = 0; 29d1d6cd26 2012-07-21 kinaba: for(int i=0,m=1; i<NH; ++i,m*=3) 29d1d6cd26 2012-07-21 kinaba: { 29d1d6cd26 2012-07-21 kinaba: int v = (state/m)%3; 29d1d6cd26 2012-07-21 kinaba: if( v == 1 ) { 29d1d6cd26 2012-07-21 kinaba: int y = hats[i].first; 29d1d6cd26 2012-07-21 kinaba: int x = hats[i].second; 29d1d6cd26 2012-07-21 kinaba: yoko[y]++; 29d1d6cd26 2012-07-21 kinaba: tate[x]++; 29d1d6cd26 2012-07-21 kinaba: ++cnt; 29d1d6cd26 2012-07-21 kinaba: } else if( v == 2 ) { 29d1d6cd26 2012-07-21 kinaba: next.push_back(m); 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: if( next.empty() ) 29d1d6cd26 2012-07-21 kinaba: { 29d1d6cd26 2012-07-21 kinaba: if( cnt != NC ) 29d1d6cd26 2012-07-21 kinaba: return false; 29d1d6cd26 2012-07-21 kinaba: for(int y=0; y<yoko.size(); ++y) 29d1d6cd26 2012-07-21 kinaba: if(yoko[y]%2 != 0) 29d1d6cd26 2012-07-21 kinaba: return p_memo[state] = false; 29d1d6cd26 2012-07-21 kinaba: for(int x=0; x<tate.size(); ++x) 29d1d6cd26 2012-07-21 kinaba: if(tate[x]%2 != 0) 29d1d6cd26 2012-07-21 kinaba: return p_memo[state] = false; 29d1d6cd26 2012-07-21 kinaba: return p_memo[state] = true; 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: else 29d1d6cd26 2012-07-21 kinaba: { 29d1d6cd26 2012-07-21 kinaba: int m = next[0]; 29d1d6cd26 2012-07-21 kinaba: int s[] = {state-2*m, state-m}; 29d1d6cd26 2012-07-21 kinaba: return p_memo[state] = ( is_possible(s[0]) || is_possible(s[1]) ); 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: vector<char> b_memo; 29d1d6cd26 2012-07-21 kinaba: vector<bool> b_memo_set; 29d1d6cd26 2012-07-21 kinaba: char best_num(int state, int guess) 29d1d6cd26 2012-07-21 kinaba: { 29d1d6cd26 2012-07-21 kinaba: if( guess==0 ) 29d1d6cd26 2012-07-21 kinaba: return 0; 29d1d6cd26 2012-07-21 kinaba: if(b_memo_set[state]) 29d1d6cd26 2012-07-21 kinaba: return b_memo[state]; 29d1d6cd26 2012-07-21 kinaba: b_memo_set[state] = true; 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: char best = 0; 29d1d6cd26 2012-07-21 kinaba: for(int i=0,m=1; i<NH; ++i,m*=3) 29d1d6cd26 2012-07-21 kinaba: { 29d1d6cd26 2012-07-21 kinaba: int v = (state/m)%3; 29d1d6cd26 2012-07-21 kinaba: if( v == 2 ) 29d1d6cd26 2012-07-21 kinaba: { 29d1d6cd26 2012-07-21 kinaba: int s[] = {state-2*m, state-m}; 29d1d6cd26 2012-07-21 kinaba: char score = 13; 29d1d6cd26 2012-07-21 kinaba: if( is_possible(s[0]) ) 29d1d6cd26 2012-07-21 kinaba: score = min(score, best_num(s[0], guess-1)); 29d1d6cd26 2012-07-21 kinaba: if( is_possible(s[1]) ) 29d1d6cd26 2012-07-21 kinaba: score = min<char>(score, best_num(s[1], guess-1)+1); 29d1d6cd26 2012-07-21 kinaba: best = max(best, score); 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: return b_memo[state] = best; 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: }; 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: // BEGIN CUT HERE 29d1d6cd26 2012-07-21 kinaba: #include <ctime> 29d1d6cd26 2012-07-21 kinaba: double start_time; string timer() 29d1d6cd26 2012-07-21 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 29d1d6cd26 2012-07-21 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 29d1d6cd26 2012-07-21 kinaba: { os << "{ "; 29d1d6cd26 2012-07-21 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 29d1d6cd26 2012-07-21 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 29d1d6cd26 2012-07-21 kinaba: void verify_case(const int& Expected, const int& Received) { 29d1d6cd26 2012-07-21 kinaba: bool ok = (Expected == Received); 29d1d6cd26 2012-07-21 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 29d1d6cd26 2012-07-21 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 29d1d6cd26 2012-07-21 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 29d1d6cd26 2012-07-21 kinaba: #define END verify_case(_, MagicalHats().findMaximumReward(board, coins, numGuesses));} 29d1d6cd26 2012-07-21 kinaba: int main(){ 29d1d6cd26 2012-07-21 kinaba: 29d1d6cd26 2012-07-21 kinaba: CASE(0) 29d1d6cd26 2012-07-21 kinaba: string board_[] = {"H"}; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = {1}; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = 1; 29d1d6cd26 2012-07-21 kinaba: int _ = 1; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: CASE(1) 29d1d6cd26 2012-07-21 kinaba: string board_[] = {"HHH", 29d1d6cd26 2012-07-21 kinaba: "H.H", 29d1d6cd26 2012-07-21 kinaba: "HH."}; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = {9}; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = 1; 29d1d6cd26 2012-07-21 kinaba: int _ = 9; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: CASE(2) 29d1d6cd26 2012-07-21 kinaba: string board_[] = {"HH", 29d1d6cd26 2012-07-21 kinaba: "HH"}; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = {1,2,3,4}; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = 3; 29d1d6cd26 2012-07-21 kinaba: int _ = 6; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: CASE(3) 29d1d6cd26 2012-07-21 kinaba: string board_[] = {"HHH", 29d1d6cd26 2012-07-21 kinaba: "HHH", 29d1d6cd26 2012-07-21 kinaba: "H.H"}; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = {13,13,13,13}; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = 2; 29d1d6cd26 2012-07-21 kinaba: int _ = 13; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: CASE(4) 29d1d6cd26 2012-07-21 kinaba: string board_[] = {"HHH", 29d1d6cd26 2012-07-21 kinaba: "HHH", 29d1d6cd26 2012-07-21 kinaba: "H.H"}; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = {13,13,13,13}; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = 3; 29d1d6cd26 2012-07-21 kinaba: int _ = 26; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: CASE(5) 29d1d6cd26 2012-07-21 kinaba: string board_[] = {"H.H.", 29d1d6cd26 2012-07-21 kinaba: ".H.H", 29d1d6cd26 2012-07-21 kinaba: "H.H."}; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = {17}; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = 6; 29d1d6cd26 2012-07-21 kinaba: int _ = -1; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: CASE(6) 29d1d6cd26 2012-07-21 kinaba: string board_[] = {"HHH..........", 29d1d6cd26 2012-07-21 kinaba: "H.H..........", 29d1d6cd26 2012-07-21 kinaba: "HHH..........", 29d1d6cd26 2012-07-21 kinaba: "H.H..........", 29d1d6cd26 2012-07-21 kinaba: "HHH.........." 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: }; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = {33,337,1007,2403,5601,6003,9999}; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = 5; 29d1d6cd26 2012-07-21 kinaba: int _ = 1377; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: CASE(7) 29d1d6cd26 2012-07-21 kinaba: string board_[] = {".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".....H.H.....", 29d1d6cd26 2012-07-21 kinaba: "......H......", 29d1d6cd26 2012-07-21 kinaba: ".....H.H.....", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: ".............", 29d1d6cd26 2012-07-21 kinaba: "............."}; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = {22}; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = 3; 29d1d6cd26 2012-07-21 kinaba: int _ = 22; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: /* 29d1d6cd26 2012-07-21 kinaba: CASE(8) 29d1d6cd26 2012-07-21 kinaba: string board_[] = ; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = ; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = ; 29d1d6cd26 2012-07-21 kinaba: int _ = ; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: CASE(9) 29d1d6cd26 2012-07-21 kinaba: string board_[] = ; 29d1d6cd26 2012-07-21 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 29d1d6cd26 2012-07-21 kinaba: int coins_[] = ; 29d1d6cd26 2012-07-21 kinaba: vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 29d1d6cd26 2012-07-21 kinaba: int numGuesses = ; 29d1d6cd26 2012-07-21 kinaba: int _ = ; 29d1d6cd26 2012-07-21 kinaba: END 29d1d6cd26 2012-07-21 kinaba: */ 29d1d6cd26 2012-07-21 kinaba: } 29d1d6cd26 2012-07-21 kinaba: // END CUT HERE