BZOJ1026: [SCOI2009]windy数

2021-02-16 08:17

阅读:407

【数据规模和约定】

100%的数据,满足 1

 

题目传送门

话说博客园这个链接有点难看。。。

换了个新环境,就学点新东西吧——数位DP

第一次做这种题还是很难搞的,%一发题解吧,没题解不能活系列

我们设f[i][j]代表i位,最高为j的数有多少是Windy数,那么我都能想到方程:f[i][j]=Sigma(f[i-1][k])(abs(k-j)>=2)

但是我们要求的是数啊,那么就得拆,拆开之后,对于每一位进行记录即可

代码如下(感觉代码讲的比我讲的清楚):

#include
#include
#include
#includeusing namespace std;
int f[20][20],a[110000];
typedef long long ll;
void dp()
{
    for(int i=0;i9;i++)f[1][i]=1;
    for(int i=2;i12;i++)
        for(int j=0;j9;j++)
            for(int k=0;k9;k++)
                if(abs(j-k)>=2) f[i][j]+=f[i-1][k];
}
ll get_a(ll x)
{
    ll len=0;
    while(x)
    {
        a[++len]=x%10;
        x/=10;
    }
    return len;
}
ll findans(ll len)
{
    ll ans=0;
    for(int i=1;i)
        for(int j=1;j9;j++)ans+=f[i][j];
    for(int i=1;i)
        ans+=f[len][i];
    for(int i=len-1;i>=1;i--)
    {
        for(int j=0;j)
        if(abs(a[i+1]-j)>=2)ans+=f[i][j];
        if(abs(a[i+1]-a[i])2)break;
    }
    return ans;
}
int main()
{
    memset(f,0,sizeof(f));
    int x,y;
    scanf("%d%d",&x,&y);
    if(x>y){int tt=x;x=y;y=tt;}
    dp();
    ll lena=get_a(x),ansa=findans(lena);
    ll lenb=get_a(++y),ansb=findans(lenb);
    printf("%lld\n",ansb-ansa);
    return 0;
}

by_lmy


评论


亲,登录后才可以留言!