动态规划-数位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;
}

猜你喜欢

转载自www.cnblogs.com/mch5201314/p/10324874.html