月数をACWING /羅区同様の分布

考え

一般的には、デジタルDPは心の中で検索して行うことができ、私たちは心の検索でこの質問を考え

まず、番号を見つけると、数字の合計が割り切れるかどうかを判断するために、各番号は一度判断しなければならないので、彼のアイデアは、間違っている、検索が暴力的な検索になります覚えています。

、アイデアを変換係数がゼロですので、あなたは最後の数字は、弾性率0であるかを決定するためにカウントし、動作するように、各段階の係数を考慮することができる割り切れます

しかし、我々はそれがどのくらいの数字と分からないのですか?問題ではありません列挙には十分を知りませんあなたは数字と暴力の小型、直接列挙、最後の検索が値と列挙するかどうかを判断します。


C ++コード

#include<bits/stdc++.h>
using namespace std;
#define go(i,a,b) for(int i=(a);i<=(b);++(i))
#define com(i,a,b) for(int i=(a);i>=(b);--(i))
#define mem(a,b) memset((a),(b),sizeof(a))
#define inf 0x3f3f3f3f
#define fin freopen("input.txt","r",stdin)
#define fout freopen("output.txt","w",stdout)
typedef long long ll;
const int maxn=100010;
int num[20],n,p;
ll f[20][200][200],_pow[20];

ll dfs(int len,int sum,bool limit,int mod){
    if(!len){
        if(sum==p&&!mod) return 1;
        return 0;
    }
    if(!limit&&f[len][sum][mod]!=-1) return f[len][sum][mod];
    int up=limit?num[len]:9;
    ll ret=0;
    go(i,0,up){
        ret+=dfs(len-1,sum+i,limit&&i==num[len],(mod*10+i)%p);
    }
    return f[len][sum][mod]=ret;
}

ll solve(ll val){
    n=0;
    while(val){
        num[++n]=val%10;
        val/=10;
    }
    ll ans=0;
    for(p=1;p<=200;p++)
    mem(f,-1),ans+=dfs(n,0,1,0);
    return ans;
}

signed main(){ 
    //fin;
    ll a,b;
    scanf("%lld%lld",&a,&b);
    printf("%lld",solve(b)-solve(a-1));
    return 0;
}

おすすめ

転載: www.cnblogs.com/White-star/p/11469671.html