HDU6156 Palindrome Function數位dp

題意:求L~R所有的數的l~r進制的f(x,k進制), 如果x是迴文串f(x,k進制) = k, 否則等於1;

枚舉進制,求出每一種情況,注意膜k,不是膜10,T_T調了好久才發現錯在這;

題解:dp[pos][start][similar][basic]表示basic進制下,處理到完pos位,從start位開始,similar狀態下回文串的個數。則記憶化搜索下即可。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int dp[32][32][2][37];
int tmp[32], dight[32];

int dfs(int pos, int start, bool similar, bool limit, int basic)
{
    if(!pos) return similar;
    int &A = dp[pos][start][similar][basic];
    if(~A && !limit) return A;
    int up = limit ? dight[pos] : basic - 1, res = 0;
    for(int i = 0;i <= up;i ++) {
        tmp[pos]  = i;
        if(i == 0 && pos == start) {
            res += dfs(pos-1, start-1, similar, limit && i == dight[pos], basic);
        } else if(similar && pos < start / 2 + 1) {
            res += dfs(pos-1, start, similar && i == tmp[start+1-pos], limit && i == dight[pos], basic);
        } else {
            res += dfs(pos-1, start, similar, limit && i == dight[pos], basic);
        }
    }
    if(!limit) A = res;
    return res;
}

int solve(int n, int k)
{
    int cnt = 0;
    while(n) {
        dight[++cnt] = n % k;
        n /= k;
    }
    return dfs(cnt, cnt, 1, 1, k);
}
int main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    int T, Case = 0;
    int L, R, l, r;
    memset(dp, -1, sizeof(dp));
    cin >> T;
    while(T --) {
        cin >> L >> R >> l >> r;
        ll res = 0;
        for(int i = l;i <= r;i ++) {
            ll t = solve(R, i) - solve(L-1, i);
            res += t * i + R - L + 1 - t;
        }
        cout << "Case #" << ++Case << ": ";
        cout << res << '\n';
    }
    return 0;
}


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