codeforces 55D Beautiful numbers

寫了兩道數位dp了 還是比較朦朧


#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <iterator>
#include <cmath>
#include <deque>
#include <stack>
#include <cctype>
#include <iomanip>
using namespace std;

typedef long long ll;
typedef long double ld;

const int N = 10;
const int INF = 0xfffffff;
const double EPS = 1e-8;
const ll MOD = 1e9 + 7;
const ld PI = acos (-1.0);

#define INFL 0x7fffffffffffffffLL
#define met(a, b) memset(a, b, sizeof(a))
#define put(a) cout << setiosflags(ios::fixed) << setprecision(a)

int t, bit[20], A[2521];
ll dp[19][48][252], l, r;

int gcd (int a, int b);
ll calc (ll n);
ll dfs (int len, int lcm, int mod, bool ismax);

int main ()
{
    for (int i=1, s=-1; i<2521; A[i]=s+=(2520%i==0), i++);
    met (dp, -1);
    for (cin>>t; t--; cin>>l>>r, cout<<calc(r)-calc(l-1)<<endl);
    return 0;
}

ll calc (ll n)
{
    int len = 0;
    for (; n; bit[len++]=n%10, n/=10);
    return dfs (len-1, 1, 0, true);
}

ll dfs (int len, int lcm, int mod, bool ismax)
{
    if (len == -1)
        return mod % lcm == 0;
    if (!ismax && dp[len][A[lcm]][mod] != -1)
        return dp[len][A[lcm]][mod];
    ll cnt = 0;
    int maxnum = ismax ? bit[len] : 9;
    for (int i=0; i<=maxnum; i++)
        cnt += dfs (len-1, i?lcm*i/gcd(lcm, i):lcm, len?(mod*10+i)%252:(mod*10+i), ismax && i == maxnum);
    return ismax ? cnt : dp[len][A[lcm]][mod] = cnt;
}

int gcd (int a, int b)
{
    return b ? gcd (b, a%b) : a;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章