zoukankan      html  css  js  c++  java
  • Windy 数

    题目链接:https://loj.ac/problem/10165#submit_code

    思路:数位dp,记录是否为前导0,已经是否为上边界和前一个数的值即可,如果前面已经有数了,那要和前一个数之差的绝对值要大于等于2才行。具体实现请看代码。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int a[30];
    ll dp[30][20];
    //pos : 位数  qd : 是否为前导  flag : 是否处于上边界   x : 上一个位数的值
    ll dfs(int pos,bool qd,bool flag,int x)
    {
        if(pos==0)
            return 1;
        int up=flag?a[pos]:9;//确定上边界
        if((!flag)&&(!qd)&&dp[pos][x]!=-1)//如果之前已经求出,则直接返回
            return dp[pos][x];
        ll tmp=0;
        for(int i=0;i<=up;i++)
        {
            if(i==0&&qd)//依旧是前导0
                tmp+=dfs(pos-1,qd,flag&&i==a[pos],0);
            else if(qd)//前面的数是前导0,这是第一个数,不需要考虑差要大于等于2
                tmp+=dfs(pos-1,false,flag&&i==a[pos],i);
            else if(abs(i-x)>=2)//要保证两个数的差大于等于2
                tmp+=dfs(pos-1,false,flag&&i==a[pos],i);
        }
        if((!flag)&&(!qd))
            dp[pos][x]=tmp;//记录值,方便下次直接返回
        return tmp;
    }
    ll fun(int x)
    {
        int pos=0;
        while(x)//将x的每一位进行分解
        {
            a[++pos]=x%10;
            x/=10;
        }
        return dfs(pos,true,true,0);
    }
    int main()
    {
        memset(dp,-1,sizeof(dp));
        int l,r;
        cin>>l>>r;
        cout<<fun(r)-fun(l-1)<<endl;
    }
  • 相关阅读:
    mysql 存储过程中的 prepare语句(存储过程中动态增减表字段)
    MYSQL创建分区时候报错
    mysql存储过程调试方法
    磁力块[分块]
    区间最优覆盖问题[差分]
    区间最优覆盖问题[差分]
    导弹防御[差分]
    导弹防御[差分]
    CF10D LCIS[动态规划]
    CF10D LCIS[动态规划]
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/13749082.html
Copyright © 2011-2022 走看看