牛客寒假算法基础集训营3处女座和小姐姐(三) (数位dp)

链接:https://ac.nowcoder.com/acm/contest/329/G
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

经过了选号和漫长的等待,处女座终于拿到了给小姐姐定制的手环,小姐姐看到以后直呼666!

处女座其实也挺喜欢6这个数字的,实际上他做手环的时候选取的k=6。所以他对于包含数码6的数字极其敏感。每次看到像4567这样的数字的时候他的心就像触电了一样,想起了小姐姐。

现在你要给处女座展示一系列数字,你想知道他的内心会激动多少次。对于同一个数字,他最多只会激动一次,即如果这个数是66666,他还是只会激动一次。

输入描述:

一行包括两个数字l,r,表示你给处女座展示的数字范围为[l,r]。

输出描述:

一行一个整数,表示处女座内心激动的次数。
示例1

输入

复制
10 20

输出

复制
1

备注:

0lr10180≤l≤r≤1018

解题思路:很明显的数位dp
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<cmath>
#include<list>
#include<deque>
#include<cstdlib>
#include<bitset>
#include<stack>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=10007;
const int maxn=1000005;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
ll n,m,a[20];
ll dp[20][20];
ll dfs(ll pos,int state,bool limit) //state表示是否还有6,有6为1,没有6位0
{
    if(pos==-1)
        return state;
    if(!limit&&dp[pos][state]!=-1)
        return dp[pos][state];
    ll up=limit?a[pos]:9;
    ll ans=0;
    for(int i=0;i<=up;i++)
    {
        if(i==6)ans+=dfs(pos-1,1,limit&&i==a[pos]);
        else ans+=dfs(pos-1,state,limit&&i==a[pos]);
    }
    if(!limit)
        dp[pos][state]=ans;
    return ans;
}
ll solve(ll x)
{
    ll pos=0;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,0,true);
}
int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0);
    memset(dp, -1, sizeof(dp));
    while(cin>>n>>m)
        cout<<solve(m)-solve(n-1)<<endl;
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/zjl192628928/p/10326047.html