SRM 412 DIV1 Easy - ForbiddenStrings ○

問題


http://community.topcoder.com/stat?c=problem_statement&pm=8480&rd=13503

A,B,Cからなる文字列がある。
ただし、AとBとCが連続して3つ並ばないようにしたい。
文字列の長さnが与えられたとき、そのような文字列の総数を求める。

解き方


dpで解けそうな問題。

前の状態として直前2つの文字が何であったか覚えていればよいので、
dp[現在位置][2つ前までのAの有無][2つ前までのBの有無][2つ前までのCの有無]
としてあげればよい。

コード


class ForbiddenStrings {

public: long long countNotForbidden(int n) {
long long dp[n+1][4][4][4];

memset(dp,0,sizeof(dp));
dp[0][0][0][0]=1;

FORE(i,0,n)FORE(j,0,4)FORE(k,0,4)FORE(l,0,4){
int nextj=(j&1)<<1;
int nextk=(k&1)<<1;
int nextl=(l&1)<<1;
if(!(k && l))dp[i+1][nextj|1][nextk][nextl]+=dp[i][j][k][l];
if(!(j && l))dp[i+1][nextj][nextk|1][nextl]+=dp[i][j][k][l];
if(!(j && k))dp[i+1][nextj][nextk][nextl|1]+=dp[i][j][k][l];
}

long long ret=0;
FORE(i,0,4)FORE(j,0,4)FORE(k,0,4)ret+=dp[n][i][j][k];

return ret;
}

};
このエントリーをはてなブックマークに追加