2017-07-05(数位DP:windy数)

来源:互联网 发布:平安 云计算 编辑:程序博客网 时间:2024/06/02 02:50

数位DP:windy数
dp[i][j]表示从0到长度为i,首位数是j的数有多少个windy数
首先要初始化,从个数为1到个数为10,首位数从0到9
*一定不能忘记0*

inline void init(){    for (int i=0;i<=9;i++)        dp[1][i]=1;    for (int i=2;i<=10;i++)        for (int j=0;j<=9;j++)            for (int k=0;k<=9;k++)                if (abs(j-k)>=2)                    dp[i][j]+=dp[i-1][k];}

将数进行拆分如x=123456789

    while(x){        t++;        b[t]=x%10;        x=x/10;    }

ans分三步相加(t为数位的个数)
STEP1:从正数第二位加到倒数第一位

    for (int i=1;i<t;i++)        for (int j=0;i<=9;i++)            ans+=dp[i][j];

STEP2:将长度为最长,首位大小小于x首位的windy数进行相加

    for (int i=0;i<b[t];i++)        ans+=dp[t][i];

STEP3:加上最后剩下的部分

    for (int i=t-1;i>=1;i--){        for (int j=0;j<=9;j++)            if (abs(j-b[i])>=2)                ans+=dp[i][j];        if (abs(b[i]-b[i+1])<2)            break;    }