您的位置:首页 > 其它

hdu 4734 数位dp

2016-02-20 13:43 330 查看
题目:点击打开链接

题意:给一个数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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: