SRM504 Div1 Medium(500) AlgridTwo
次の行に移った時、前の行は出力と同じになっているはずなので、行ごとに何通りの入力があるかを求めて掛け合わせればよい。
行ごとのありうる入力の個数は動的計画法で求める。あるマスの1つ前まで処理を行って、そのマスが白や黒になった場合に何通りかをそれぞれ覚えておく。
#include <vector> #include <numeric> using namespace std; class AlgridTwo{public: int makeProgram( vector <string> output ) { int M = 1000000007; int H = (int)output.size(); int W = (int)output[0].size(); long long ans = 1; for ( int y=1; y<H; y++ ) { // ここより前の処理で色が白/黒になる場合、以降何通りの入力がありうるか long long w, b; if ( output[y][W-1]=='W' ) w=1, b=0; else b=1, w=0; for ( int x=W-2; x>=0; x-- ) { long long nw = w; long long nb = b; if ( output[y-1][x]=='W' && output[y-1][x+1]=='W' ) { if ( output[y][x]=='W' ) w = nw+nb, b = 0; if ( output[y][x]=='B' ) b = nb+nw, w = 0; } if ( output[y-1][x]=='B' && output[y-1][x+1]=='W' ) { if ( output[y][x]=='W' ) w = b = 0; if ( output[y][x]=='B' ) w = b = nb*2; } if ( output[y-1][x]=='W' && output[y-1][x+1]=='B' ) { if ( output[y][x]=='W' ) w = b = nw*2; if ( output[y][x]=='B' ) w = b = 0; } if ( output[y-1][x]=='B' && output[y-1][x+1]=='B' ) { w = nw, b = nb; } w %= M; b %= M; } ans = ans * (w+b) % M; } return (int)ans; }};