• Palindrome Function HDU


    要求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
    ", cas++, ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Android 锁屏消息调研
    [GODOT]可复用移动组件(载具类)
    [GODOT]技能系统初探
    [GODOT]获取节点
    美丽的秋天
    生活
    day7.17
    html
    day 2015.6.08
    不会转载只能先留下网址了
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/9394538.html
Copyright © 2020-2023  润新知