首页 > 其他 > 详细

【数位DP】二四六七八

时间:2020-06-05 09:47:48      阅读:51      评论:0      收藏:0      [点我收藏+]

二四六七八

题意:对于每组数据给定的 \(x\)\(y\) , 求 \([x,y]\) 内各个数位仅由 \(2,4,6,7,8\) 构成的数的个数。其中\(1≤x≤y≤10^{18}\)

思路:
算是板子题。卡住的点主要还是不清楚什么时候前导零是必须的。
另外不开longlong见祖宗

LL dp[20];
int a[20];

LL dfs(int pos,bool lead,bool limit){
    LL ans = 0;
    if (pos == -1) return 1;
    if (!limit && !lead && dp[pos] != -1) return dp[pos];
    int end = limit ? a[pos] : 9;
    for (int i = 0; i <= end; i++) {
        if (i == 1 || i == 3 || i == 5 || i == 9) continue;
        if (!lead && (!i)) continue;
        //0是不合法的,如果没有前导零,这一位又是零,就跳过
        ans += dfs(pos - 1, lead&&(!i), limit && i == end);
        //如果有前导零且这一位也是零,那么这一位也是前导零
        //否则如果有前导零且这一位不是零,则不是前导零
    }
    if (!limit&&!lead)  dp[pos] = ans;
    //没有前导零也没有最高位限制,说明本次统计结果是通用的
    return ans;
}

LL part(LL x){
    int len = 0;
    LL k = x;
    while (k) {
        a[len++] = k % 10;
        k /= 10;
    }
    memset(dp, -1, sizeof (dp));
    return dfs(len - 1, true, true);
}

int main()
{
    ios::sync_with_stdio(false);
    int t; cin >> t; while (t--){
       LL l, r;
       cin >> l >> r;
       cout << part(r) - part(l-1)<<endl;
    }
    return 0;
}

【数位DP】二四六七八

原文:https://www.cnblogs.com/streamazure/p/13047530.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!