• 洛谷P2657 windy数


    传送

    裸的数位dp

    看这个题面,要求相邻两个数字之差至少为2,所以我们记录当前填的数的最后一位

    同时要考虑毒瘤的前导0。如果填的数前面都是0,则这一位填0是合法的。

    emmm具体的看代码叭

    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define pa pair<int,int>
    typedef long long ll;
    using namespace std;
    const int inf=214748364;
    inline ll read()
    {
        char ch=getchar();
        ll x=0;bool f=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<3)+(x<<1)+(ch^48);
            ch=getchar();
        }
        return f?-x:x;
    }
    ll a,b,f[15][10],li[15],t;//li[i]表示在顶上界的时候第i为最大是多少
    void ma(ll r)
    {
        t=0;
        memset(li,0,sizeof(li));
        while(r)
        {
            li[++t]=r%10;
            r/=10;
        }
        
    }
    ll sol(int now,int lst,bool lim,bool al)//now记录填到第now位,lst是上一位填的数,lim表示是否顶上界,al表示是否前面都是0
    {
        if(now==0)return 1;
        if(!al&&!lim&&f[now][lst]!=-1)return f[now][lst];
        int up=lim?li[now]:9;
        ll rtn=0;
        for(int i=0;i<=up;i++)
        {
            if((abs(lst-i)<2)&&!al)continue;
            rtn+=sol(now-1,i,(lim&&(i==up)),((i==0)&&al));
        }
        if(!al&&!lim)f[now][lst]=rtn;
        return rtn;
    }
    
    int main()
    {
        memset(f,-1,sizeof(f));
        a=read();b=read();
        ma(b);//先对[1,b]搞一遍
        ll ans=sol(t,0,1,1);
        ma(a-1);//再对[1,a-1]搞一遍
        ll an=sol(t,0,1,1);
        ans-=an;
        printf("%d",ans);
    }
  • 相关阅读:
    dotnet Framework 源代码 类库的意思
    dotnet Framework 源代码 类库的意思
    dotnet Framework 源代码 · Ink
    dotnet Framework 源代码 · Ink
    dotnet core 用值初始化整个数组
    dotnet core 用值初始化整个数组
    dotnet core 隐藏控制台
    dotnet core 隐藏控制台
    PHP mt_rand() 函数
    PHP mt_getrandmax() 函数
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/11355812.html
Copyright © 2020-2023  润新知