HDU 2089 不要62(数位dp)

题目传送门

题意: 在给定区间 [ n , m ] [n,m] [n,m]内,寻找有多少个数字的数位中,不包含4或者62。

思路: 考虑使用前缀和思想, a n s [ i ] ans[i] ans[i]表示从 [ 0 , i ] [0,i] [0,i]中有多少个符合的数字,处理出 a n s [ m ] − a n s [ n − 1 ] ans[m]-ans[n-1] ans[m]ans[n1]

代码:

#include<bits/stdc++.h>
#define endl '\n'
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
    int x=0,f=1;
    char ch=gc();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
using namespace std;
const int N=1e3+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int a[N],len=0,f[15][15];

int dfs(int pos,int pre,int limit)
{
    if(pos==0) return 1;
    if(!limit&&f[pos][pre]!=-1) return f[pos][pre];
    int high = limit?a[pos]:9,res=0;
    for(int i=0;i<=high;i++)
    {
        if(i==4||(i==2&&pre==6)) continue;
        res+=dfs(pos-1,i,limit&&i==high);
    }
    if(!limit) f[pos][pre] = res;
    return res;
}
int work(int x)
{
    len=0;
    while(x) a[++len]=x%10,x/=10;
    //mem(f,-1);
    return dfs(len,0,1);
}
void solve()
{
    mem(f,-1);
    int n,m;
    while(cin>>n>>m)
    {
        if(n+m==0) break;
        cout<<work(m)-work(n-1)<<endl;
    }
}
signed main()
{
//    int _;
//    cin>>_;
//    while(_--)
        solve();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值