windy定义了一种windy数,不含前导零且前两个数字只差至少为2的正整数被称为windy数,求A和B之间windy数的个数

windy定义了一种windy数,不含前导零且前两个数字只差至少为2的正整数被称为windy数,求AB之间windy数的个数

1.优化子结构: 

    d[ij]代表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位数,其中最高位为kWindy数个数。

  证明如下:

  假设d[i-1,m](m属于k)不是为i-1位数,其中最高位为mWindy数个数。不妨设d'[i-1,m]>d[i-1,m]因为任意m属于k,|m-j|≥2,那么再加上一位j 仍为Windy,所以d'[ij]=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

点赞