hdu3709【数位dp】

数位dp

枚举平衡节点就好



#include <cmath>
#include <cstdio>
#include <cstring>
#define LL long long

using namespace std;

LL l,r,ans;

LL a[30],b[30],la,lb;

LL dp[30][2000];
LL vis[30][2000];
LL poi;

LL dfs (LL u,bool ulim,bool dlim,LL be_val) {
	if(u == 0) {
		if(!be_val)
			return 1;
		return 0;
	}
	
	LL en = ulim ? b[u] : 9;
	LL st = dlim ? a[u] : 0;
	
	if(!(ulim || dlim)) {
		if(vis[u][be_val] == poi)
			return dp[u][be_val];
		else vis[u][be_val] = poi;
	}
	LL t = 0;
	for(LL i = st;i <= en;++i) {
		bool ulimt = i == b[u] && ulim;
		bool dlimt = i == a[u] && dlim;
		if(be_val + (u - poi) * i < 0)
			continue;
		t += dfs(u - 1,ulimt,dlimt,be_val + (u - poi) * i);
	}
	if(!(ulim || dlim))
		dp[u][be_val] = t;
	return t;
}

int main () {
	int T;
	scanf("%d",&T);
	
	while(T--) {
		ans = 0;
		memset(vis,-1,sizeof vis);
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		scanf("%I64d%I64d",&l,&r);
		
		if(l)
			la = log10(l) + 1;
		else la = 1;
		if(r)
			lb = log10(r) + 1;
		else lb = 1;
		for(LL i = 1;l;++i) {
			a[i] = l % 10;
			l /= 10;
		}
		
		for(LL i = 1;r;++i) {
			if(i > la)
				a[i] = 0;
			b[i] = r % 10;
			r /= 10;
		}
		
		for(LL i = 1;i <= lb;++i) {
			poi = i;
			ans += dfs(lb,1,1,0);
		}
		if(la == 1 && !a[1]) {
			ans -= lb;++ans;
		}
		printf("%I64d\n",ans);	
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值