[HDU3709]Balanced Number && 数位DP

递推四维状态写的我无比纠结 最后无奈弃坑 搞记忆化搜索了 这道题多的一个是要枚举支点o 然后从高位往低位考虑的时候注意力矩是否为正值

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const int MAXN = 18;
const int MAXL = 2000;
int bit[MAXN+10];
LL d[MAXN+10][MAXN+10][MAXL+10];
LL dp(int i, int o, int pre, int limit)
{
	if(i <= 0) return pre == 0;
	if(pre < 0) return 0;
	if(!limit && d[i][o][pre] != -1) return d[i][o][pre];
	LL ans = 0;
	for(int j = 0; j <= (limit ? bit[i] : 9); j++)
		ans += dp(i-1, o, pre + j * (i - o), limit && (j == (limit ? bit[i] : 9)));
	if(!limit) d[i][o][pre] = ans;
	return ans;
}
LL solve(LL X)
{
	int Len = 0; LL ans = 0;
	memset(bit, 0, sizeof(bit));
	while(X) {
		bit[++Len] = X % 10;
		X /= 10;
	}
	for(int i = 1; i <= Len; i++) 
		ans += dp(Len, i, 0, 1);
	return ans - Len + 1;
}
int main()
{
	memset(d, -1, sizeof(d));
	int T; scanf("%d", &T); while(T--) {
		LL L, R;
		cin >> L >> R;
		LL ans = solve(R) - solve(L-1);
		cout << ans << '\n';
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值