您的位置:首页 > 其它

HDU 4734 F(x) 数位DP .

2016-10-09 08:45 204 查看
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4734

状态定义为d[pos][weight]

一开始我DFS时候从前往后加权值

但这无法记忆化

所以可以从前往后减去权值

d[pos][weight] 代表在pos这一位开始枚举,小于等于weight的数有几个

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxp=11;
int digit[maxp],base[maxp];
int d[maxp][5001];
int DFS(int pos,int pWeight,bool limit)
{
if(pos==-1) return pWeight>=0;
if(pWeight<0) return 0;

int& ans=d[pos][pWeight];
if(!limit && ans!=-1) return ans;
int temp=0,up=limit?digit[pos]:9;
for(int i=0;i<=up;i++)
temp+=DFS(pos-1,pWeight-i*base[pos],limit&&i==up);

if(!limit) ans=temp;
return temp;
}
int f(int n) // get f(A)
{
int p=0,ans=0;
while(n){
ans+=n%10*base[p++];
n/=10;
}
return ans;
}
int solve(int B,int A)
{
int len=0;
while(B){
digit[len++]=B%10;
B/=10;
}
return DFS(len-1,f(A),true);
}
int main(int argc, char const *argv[])
{
int T,A,B,kase=0; scanf("%d",&T);

base[0]=1;
for(int i=1;i<maxp;++i)
base[i]=base[i-1]<<1;
memset(d,-1,sizeof(d));
while(T--){
scanf("%d%d",&A,&B);
printf("Case #%d: %d\n",++kase,solve(B,A));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: