Educational Codeforces Round 50 (Rated for Div. 2) C题

版权声明:https://github.com/godspeedcurry 欢迎加好友哦 https://blog.csdn.net/qq_38677814/article/details/82526312

数位dp 比赛的时候写了个暴搜没加记忆化结果gg

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll num[30];
ll f[20][2][2][20];
ll dfs(int len,bool low,bool nzero,int used){
    ll ret=0;
    if(used==4) return 0;//如果用完了返回0
    if(len==0) return 1;//搜到底说明这个数成立返回1
    if(f[len][low][nzero][used]) return f[len][low][nzero][used];//记忆化
    for(int i=0;i<=9;++i){
        if(i>num[len]&&!low) break;//如果这个数不是低位并且大于当前数位上的数 直接break
        ret+=dfs(len-1,low||i<num[len],i!=0,used+(i!=0));//往下一位搜 低位或者当前位数更小,非零,用掉一个非零的数
    }
    return f[len][low][nzero][used]=ret;//记忆化
}
ll cal(ll x){
    int len=0;
    while(x){
        num[++len]=x%10;
        x/=10;
    }
    memset(f,0,sizeof(f));
    return dfs(len,false,true,0);//从len位开始 最高位 这个初始值其实无所谓写false也可以 用了0个 
}
void solve(){
    ll l,r;
    cin>>l>>r;
    cout<<cal(r)-cal(l-1)<<endl;
}
int main(){
    int T;cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38677814/article/details/82526312