题目链接:https://vjudge.net/problem/HDU-3709
题意:有多少平衡数,例如:4139 is a balanced number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9,
题解:所以每个数的平衡位置只能有一个
dp[ i ][ j ][ k ][ z ] 表示 平衡位置是 i ,后面还剩 j 个位置,前面已经计算得到pre + 4000,z表示是否有前导0
注意一点就是,如果计算到平衡位置,前面都是0的话,那么平衡位置就不能为0,这就是前导0的左右
最后加上0这个数,因为0没有被计算到
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll dp[20][20][8000][2];
int w[66], len;
ll dfs(int pos, int limit, int pre, int ph, int lead) {
if(pos < 0) {
return pre == 4000;
}
if(!limit && dp[ph][pos][pre][lead] != -1) return dp[ph][pos][pre][lead];
int p = limit ? w[pos] : 9;
ll res = 0;
for(int i = 0; i <= p; i++) {
if(pos == ph) {
if(lead && i == 0) continue;
res += dfs(pos - 1, limit && i == p, pre, ph, 1);
} else {
res += dfs(pos - 1, limit && i == p, pre + (pos - ph) * i, ph, lead && i == 0);
}
}
if(!limit) dp[ph][pos][pre][lead] = res;
return res;
}
ll solve(ll x) {
if(x == -1) return 0;
int len = 0;
while(x) {
w[len++] = x % 10;
x /= 10;
}
ll res = 0;
for(int i = 0; i <= len - 1; i ++)
res += dfs(len - 1, 1, 4000, i, 1);
return res + 1;
}
int main() {
ll l, r;
memset(dp, -1, sizeof(dp));
int T;
scanf("%d", &T);
while(T--) {
scanf("%lld %lld", &l, &r);
printf("%lld\n", solve(r) - solve(l - 1));
}
return 0;
}