Palindrome Function HDU - 6156(数位dp)

要求m-n内在l-r进制下的是回文数的总个数。

dp[进制][从第j为开始][目前到达第k位] = 总的方案数

dfs枚举目前的到达的位置,这个数开始的位置,进制,前导零,限制条件,然后枚举的时候如果我现在是总的数的前一半,那么我就可以随意枚举,如果我已经到这个数的后一半了,那么我枚举的数字应该要满足和前面一半的这个位置对应的数,否则的话就是不满足条件的回文数,用这个数开始的位置为0来表示这个数不满足条件或者说我枚举的这个数全部都是零。然后算出这个区间内的回文数,要求sumf(i, j), 那么就是这里面的回文数乘k+不是回文数的值。

#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x & (-x))

typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 100005;
const int maxm = 1000005;
const int mod = 10007;
using namespace std;

int T, tol;
ll n, m;
int digit[100];
ll tmp[100];
ll dp[40][100][100];

ll dfs(int pos, int st, int k, bool lead, bool limit) {
    if(pos == 0)    return    st ? 1 : 0;
    if(dp[k][st][pos] != -1 && !limit)    return dp[k][st][pos];
    ll ans = 0;
    int up = limit ? digit[pos] : k-1;
    for(int i=0; i<=up; i++) {
        tmp[pos] = i;
        if(lead && i == 0)    ans += dfs(pos-1, st-1, k, lead, limit && i==digit[pos]);
        else if(pos > st/2)    ans += dfs(pos-1, st, k, 0, limit && i==digit[pos]);
        else    ans += dfs(pos-1, i==tmp[st-pos+1] ? st : 0, k, 0, limit && i== digit[pos]);
    }
    if(!limit)    dp[k][st][pos] = ans;
    return ans;
}

ll solve(ll n, int k) {
    memset(digit, 0, sizeof digit);
    int pos = 1;
    while(n) {
        digit[pos++] = n % k;
        n /= k;
    }
    return dfs(pos-1, pos-1, k, 1, 1);
}

int main() {
    int cas = 1;
    scanf("%d", &T);
    memset(dp, -1, sizeof dp);
    while(T--) {
        int l, r;
        scanf("%I64d%I64d%d%d", &m, &n, &l, &r);
        m--;
        ll ans = 0;
        for(int i=l; i<=r; i++) {
            ll cnt1 = solve(n, i);
            ll cnt2 = solve(m, i);
            ans += (cnt1 - cnt2)*i + (n-m+cnt2-cnt1);
        }
        printf("Case #%d: %I64d\n", cas++, ans);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/H-Riven/p/9394538.html