【数位DP】F(x) HDU

来源:互联网 发布:c语言while是什么意思 编辑:程序博客网 时间:2024/06/08 17:12

Think:
1知识点:数位DP
2题意:输入A,B,询问在[0, B]区间内,F(xi) <= F(A)的数的数量,其中F(x)的定义为:F(x) = An * 2^n-1 + An-1 * 2^n-2 + … + A2 * 2 + A1 * 1,其中数字x的n个数位为 (AnAn-1An-2 … A2A1)
3方法:分离B的数位作为约束条件,然后计算得到F(A),进而从F(A)的最高位开始试探,每次减少(2^pos),直到满足F(x) < F(A),记录状态值,dp数组含义:dp[i][j]表示i位数比j小的数的个数
4反思:
(1):dfs中pos == -1的状态
(2):dfs中num < 0的状态

vjudge题目链接

以下为Accepted代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int dp[24][5004], tp, link[24];int tri(int x);int dfs(int pos, int num, bool is_max);int solve(int A, int B);int main(){    memset(dp, -1, sizeof(dp));    int k = 1, T, A, B;    scanf("%d", &T);    while(T--){        scanf("%d %d", &A, &B);        printf("Case #%d: %d\n", k++, solve(A, B));    }    return 0;}int tri(int x){    int sum = 0, p = 1;    while(x){        sum += (x%10)*p;        p *= 2;        x /= 10;    }    return sum;}int solve(int A, int B){    tp = 0;    while(B){        link[tp++] = B%10;        B /= 10;    }    int num = tri(A);    return dfs(tp-1, num, true);}int dfs(int pos, int num, bool is_max){    if(pos == -1) return num >= 0;    if(num < 0) return 0;/**/    if(!is_max && ~dp[pos][num])        return dp[pos][num];    int cnt = 0, is_top = 9;    if(is_max)        is_top = link[pos];    for(int i = 0; i <= is_top; i++){        cnt += dfs(pos-1, num-i*(1<<pos), is_max && i == is_top);    }    if(!is_max)        dp[pos][num] = cnt;    return cnt;}
原创粉丝点击