动态规划-数位dp

大佬讲的清楚

[https://blog.csdn.net/wust_zzwh/article/details/52100392]

例子

不要62或4

l到r有多少个数不含62或者4

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int a, b,shu[20],dp[20][2];

int dfs(int len, bool if6, bool shangxian)
{
    if (len == 0)
        return 1;
    if (!shangxian && dp[len][if6])
        return dp[len][if6];
    int cnt = 0, maxx = (shangxian ? shu[len] : 9);
    for (int i = 0; i <= maxx; i++)
    {
        if (i == 4 || if6 && i == 2)
            continue;
        cnt += dfs(len - 1, i == 6, shangxian && i == maxx);
    }
    return shangxian ? cnt : dp[len][if6] = cnt;
}

int solve(int x)
{
    memset(shu, 0, sizeof(shu));
    int k = 0;
    while (x)
    {
        shu[++k] = x % 10;
        x /= 10;
    }
    return dfs(k, false, true);
}

int main()
{
    scanf("%d%d", &a, &b);
    if(a==0&&b==0) return 0;
    printf("%d\n", solve(b) - solve(a - 1));
    return 0;
}

不要49

l到r有多少个数不含49

代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int w[20],dp[20][2];
//dp[i][0,1]代表前一位是否为某个数的情况下,i位(0~i个9)满足条件的个数
int dfs(int len,bool is4,bool limit){
    if(len==0) return 1;
    //注意
    if(!limit&&dp[len][is4]) return dp[len][is4];
    int sum=0,maxn=(limit?w[len]:9);
    for(int i=0;i<=maxn;i++){
        if(is4&&i==9) continue;
        sum+=dfs(len-1,i==4,limit&&i==maxn);
    }
    return limit?sum:dp[len][is4]=sum;
}
int solve(int x){
    int j=0;
    memset(w,0,sizeof(w));
    while(x){
        w[++j]=x%10;
        x/=10;
    }
    return dfs(j,0,1);
}
int main(){
    int l,r;
    while(~scanf("%d%d",&l,&r)&&(l+r)){
        printf("%d\n",solve(r)-solve(l-1));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/mch5201314/p/10324874.html

时间: 2024-10-24 19:50:11

动态规划-数位dp的相关文章

[动态规划][数位dp]不要62

Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众.不吉利的数字为所有含有4或62的号码.例如:62315 73418 88914都属于不吉利号码.但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列.你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多

【luogu2657】【bzoj1026】 [SCOI2009]windy数 [动态规划 数位dp]

P2657 [SCOI2009]windy数 bzoj1026 一本通说这是一道数位dp模板题 emmmmm 就是逐位确定 f[i][j]表示填了i位数其最高位数字为j 然后就去求可能方案数 分为 不满足x的位数的严格小于x的全部情况 和x的位数相同 但最高位小于x的最高为的全部方案数 和x的位数相同 有一位比x的对应位数小的全部方案数 其余位数对应数字都相同(这是数位dp常用的一个性质:对于一个小于n的数 它从高位到低位一定会出现某一位上的数字小于n所对应这一位上的数字) PS 因为x不一定为

[动态规划][数位dp]Bomb

Problem Description The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49&quo

模板 - 动态规划 - 数位dp

#include<bits/stdc++.h> using namespace std; #define ll long long int a[20]; ll dp[20][20/*可能需要的状态1*/][20/*可能需要的状态2*/];//不同题目状态不同 ll dfs(int pos,int state1/*可能需要的状态1*/,int state2/*可能需要的状态2*/,bool lead/*这一位的前面是否为零*/,bool limit/*这一位是否取值被限制(也就是上一位没有解除限

有关动态规划(主要是数位DP)的一点讨论

动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.20世纪50年代初美国数学家在研究多阶段决策过程的优化问题时,提出了最优化原理,把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法--动态规划. ——以上内容,节选自http://baike.so.com/doc/6995222-7218096.html <<<<<<<<

数位dp/记忆化搜索

一.引例 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数: f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1 例如: f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4 给定 l, r, k,求在 [l, r] 区间中,所有 f(x) = k 的 x 的和,

数位dp详解

哈哈哈,本菜鸡经过长时间研究,终于略懂的这看似神奇的数位dp... 数位dp,顾名思义就是数位+dp,数位即是一个数的每一位上的数字,dp也就是动态规划了. 首先来讲在何时应该想到要用数位dp吧.(相信大部分人都是为了做题而学的) 数位dp的题目一般都是给定一个区间,如[l , r],然后叫你求在这区间里的数有多少个符合题目给的限制条件(解题时一般都是运用前缀和求解,即[l , r]=[0 , r]-[0 , l-1].) 其次就是讲解数位dp的原理和模板代码了.(菜鸡的我不知道讲的好不好,尽量

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是