hdu4734(数位dp)

来源:互联网 发布:c冒泡排序算法代码 编辑:程序博客网 时间:2024/06/05 18:31

基本的数位dp这几天在学 ,巩固一下,记忆化 dp[i][j] 表示长度为i位的时候不超过j的数的种数 记录的时候就用f(a)减去当前的记录的sum值就是后面的不超过的值了

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define MAXN 10int dp[MAXN][5000];int dat[20];int dfs(int len,int sum,int maxnum,bool flag){    if(sum>maxnum)    return 0;    if(len<0)    return 1;if(!flag&&dp[len][maxnum-sum]!=-1)    return dp[len][maxnum-sum];    int _end = flag?dat[len]:9;    int ans = 0;    for(int i = 0;i<=_end;i++)    {        ans += dfs(len-1,sum+i*(1<<len),maxnum,flag && i==_end);    }   // printf("dfs %d %d %d\n",len,sum,ans);    if(!flag)    {        dp[len][maxnum-sum] = ans;    }    return ans;}int Cal(int a,int b){    int len = 0;    int sum = 0;    int base = 1;    while(a!=0)    {        int Mod = a%10;        sum += Mod*base;        base <<= 1;        a/=10;    }    //printf("%d\n",sum);    while(b!=0)    {        int Mod = b%10;        dat[len++] = Mod;        b/=10;    }    return dfs(len-1,0,sum,true);}int main(){    int t;    scanf("%d",&t);    int _case = 0;    memset(dp,-1,sizeof(dp));    while(t--)    {        int ta,tb;        scanf("%d%d",&ta,&tb);         printf("Case #%d: %d\n",++_case,Cal(ta,tb));    }    return 0;}


0 0
原创粉丝点击