[BZOJ1026][SCOI2009]windy数:数位DP

分析:

没什么好说的吧,很水的一道数位DP题。
f[I][j]表示共有I位,最高位为j的windy数个数(注意这里是包含前导0的)。
输出solve(r)-solve(l-1)即可。
具体参见代码。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
int l,r,dig[11],len;
LL f[11][10];
int solve(int x){
    len=0;
    while(x){
        dig[++len]=x%10;
        x/=10;
    }
    int ans=0;
    for(int i=1;i<len;i++)
        for(int j=1;j<=9;j++)
            ans+=f[i][j];
    for(int i=1;i<dig[len];i++)
        ans+=f[len][i];
    for(int i=len-1;i;i--){
        for(int j=0;j<dig[i];j++)
            if(abs(dig[i+1]-j)>=2) ans+=f[i][j];
        if(abs(dig[i+1]-dig[i])<2) return ans;
    }
    ans++;
    return ans;
}
int main(){
    for(int i=0;i<=9;i++) f[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) f[i][j]+=f[i-1][k];
    scanf("%d%d",&l,&r);
    printf("%d\n",solve(r)-solve(l-1));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9382898.html