SRM511 Div1 Medium(500), Div2 Hard(1000) FiveHundredEleven
現在のターン数とメモリの値でどちらが勝つかが決まる。なぜならば、メモリの寝ているビットのうち少なくとも1個が立っているカードは必ず残っているし、メモリの寝ているビットが全て寝ているカードは同一視できるから。ターン数とメモリの値で勝敗を覚えておいて、メモ化探索。
#include <string> #include <vector> using namespace std; int N; vector<int> card; vector<vector<int> > memo; int BT( int t, int m ) { if ( t==N ) return -1; if ( memo[t][m] != 0 ) return memo[t][m]; int ans = -1; int c = 0; for ( int i=0; i<N; i++ ) if ( ~m & card[i] ) { if ( (m|card[i]) != 511 ) ans = max( ans, -BT(t+1,m|card[i]) ); c++; } if ( c < N-t ) ans = max( ans, -BT(t+1,m) ); return memo[t][m] = ans; } class FiveHundredEleven{public: string theWinner( vector <int> cards ) { N = (int)cards.size(); card = cards; memo = vector<vector<int> >( N, vector<int>(511) ); return BT(0,0)>0 ? "Fox Ciel" : "Toastman"; }};