windy定义了一种windy数,不含前导零且前两个数字只差至少为2的正整数被称为windy数,求A和B之间windy数的个数
1.优化子结构:
记d[i,j]代表i 位数,其中最高位为j 的Windy数个数,当最高位确定为j,根据定义,
剩下的i-1位的最高位k必定与j 相差2,,即d[i,j]=∑d[i-1,k](0≤k≤9且|k-j|≥2)。其中d[i-1,k]即为i-1位数,其中最高位为k的Windy数个数。
证明如下:
假设d[i-1,m](m属于k)不是为i-1位数,其中最高位为m的Windy数个数。不妨设d'[i-1,m]>d[i-1,m]因为任意m属于k,|m-j|≥2,那么再加上一位j 仍为Windy数,所以d'[i,j]=d'[i-1,m]+∑d[i-1,k]({k}-{m}),由此d'[i,j]>d[i,j],d[i,j]也不是代表i 位数,其中最高位为j 的Windy
数个数,这与题设相矛盾。原题得证。
2.重叠性:
d[i,j]=∑d[i-1,k] (0≤k≤9且|k-j|≥2)
d[i-1,j]=∑d[i-2,k] (0≤k≤9且|k-j|≥2)
d[i-1,j-1]=∑d[i-2,k] (0≤k≤9且|k-j|≥2)
3.状态转移方程与初始状态:
d[1,j]=1 (0<=j<=9)
d[i,j]=∑d[i-1,k] (0≤k≤9且|k-j|≥2)
4.伪代码:
function Init
fori=0 to 9
d[1][i]=1
for i=2 to 10
for j=0 to 9
for k=0 to 9
i f abs(j-k>=2) then d[i][j]+=d[i-1][k]
fucntion Count(x)
length=0
while x>0
{
windy[++length]=x%10;
x/=10;
}
for i=1 to windy[length]-1
ans+=d[lenth][i];
for i=length-1 to 0
for j=1 to 9
ans+=d[i][j];
for i=length-1 to 0
for j=0 to windy[i]-1
if abs(windy[i+1]-j)>=2 then ans+=d[i][j];
if abs(windy[i+1]-j)<2 then ans+=d[i][j];
return ans;
(3)时间复杂度:O(n3)