TopCoder SRM 300 Div1 Medium JumpyNum
問題
jumpy numberとは、隣り合う桁の数字の差の絶対値が全て2以上であるような数を言う。
low以上high以下のjumpy numberの数を求めよ。
制約条件
low,high≦2*10^9
方針
n以下のjumpy numberの数が求まればよい。
上の桁から一桁ずつ見ていく典型的なDPをする。
dp[i][j][smaller][nonzero]を、
i桁目まで見て、最後の数字がjで、
smaller=1なら今までにnの数字よりも小さい数字が出て、
nonzero=1なら今までに0でない数字が出たような状態の場合の数とする。
これに次の桁の数を0〜9まで考えてテーブルを更新していけばいい。
ソースコード
int d[20],n; int dp[20][10][2][2]; int calc(int m){ for(n=0;m;m/=10)d[n++]=m%10; reverse(d,d+n); memset(dp,0,sizeof(dp)); dp[0][0][0][0]=1; rep(i,n)rep(j,10)rep(k,2)rep(l,2){ rep(nj,10)if(k||nj<=d[i])if(abs(nj-j)>1||l==0){ int nk=k||nj<d[i], nl=l||nj; dp[i+1][nj][nk][nl]+=dp[i][j][k][l]; } } int res=0; rep(i,10)rep(j,2)res+=dp[n][i][j][1]; return res; } class JumpyNum { public: int howMany(int low, int high) { return calc(high)-calc(low-1); } };