hdu 4734 数位dp

来源:互联网 发布:美工设计的工作内容 编辑:程序博客网 时间:2024/06/05 00:08

题目:点击打开链接

题意:给一个数A (十进制表示形式为AnAn-1An-2 ... A2A1,定义函数 F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1,给一个B,求B以内的i,满足F(i)<=F(A)

分析:f[i][j]表示i位比j小的数有多少,先计算出F(a),然后dfs,找出比fa小的B以内的数,找B以内的数,这就是简单的数位dp了,先把B按位存储,然后从高位dfs一位位比较就好了。


#include <cstdio>#include <cstring>#include <vector>#include <algorithm>#include <map>#include <string>#include <iostream>#include <cmath>using namespace std;int f[11][4600];int bit[11],w[11];void init(){    memset(f,-1,sizeof(f));    for(int i=0;i<11;i++)        w[i]=1<<i;}int calc(int n){    int ans=0;    int cnt=0;    while(n){        ans+=(n%10)*w[cnt++];        n/=10;    }    return ans;}int dfs(int pos,int fa,bool lim){    if(pos<=0)return 1;    if(!lim&&f[pos][fa]!=-1)return f[pos][fa];    int num=lim?bit[pos]:9;    int ans=0;    for(int i=0;i<=num;i++){        if(fa<i*w[pos-1])continue;        ans+=dfs(pos-1,fa-i*w[pos-1],lim&&i==num);    }    if(!lim)f[pos][fa]=ans;    return ans;}int solve(int a,int b){    int len=0;    while(b){        bit[++len]=b%10;        b/=10;    }    return dfs(len,calc(a),1);}int main(){    int T,a,b;    //freopen("f.txt","r",stdin);    scanf("%d",&T);    init();    for(int t=1;t<=T;t++){        scanf("%d%d",&a,&b);       // cout<<calc(a)<<' '<<calc(b)<<endl;        printf("Case #%d: %d\n",t,solve(a,b));    }    return 0;}


0 0
原创粉丝点击