Codeforces 132 C. Logo Turtle
問題
Logo Turtleを1次元で単純化したものを考える。
命令列はF(直進)およびT(反転)からなる。
与えられた命令列をちょうどn文字(同じ文字を2度以上変更してもよい)を変更して、
命令列を全て実行した後、亀が原点から最大でどれだけ遠くまで離れられるか求めよ。
制約条件
命令列の長さ≦100
n≦50
方針
M[i][j][k]を、命令をi文字実行し、j回命令書き換えを使い、向きk(0なら前)の状態での座標の最大値とする。
同様にm[i][j][k]をその状態での座標の最小値とする。
このテーブルを愚直に更新するようなDPで間に合う。
ソースコード
int n,len; string in; int M[101][51][2],m[101][51][2]; void run() { cin>>in>>n; len=in.size(); rep(i,101)rep(j,51)rep(k,2)M[i][j][k]=-inf, m[i][j][k]=inf; M[0][0][0]=m[0][0][0]=0; rep(i,len)rep(j,n+1)rep(k,2){ for(int l=j;l<=n;l++){ if((l-j)%2^(in[i]=='F')){ M[i+1][l][k]=max(M[i+1][l][k],M[i][j][k]+(k?-1:1)); m[i+1][l][k]=min(m[i+1][l][k],m[i][j][k]+(k?-1:1)); } else{ M[i+1][l][1-k]=max(M[i+1][l][1-k],M[i][j][k]); m[i+1][l][1-k]=min(m[i+1][l][1-k],m[i][j][k]); } } } int ans=max(M[len][n][0],M[len][n][1]); ans=max(ans,max(-m[len][n][0],-m[len][n][1])); cout<<ans<<endl; }