题目链接:[kuangbin带你飞]专题十五 数位DP F - Balanced Number
题意:
给定区间[a,b],求区间内平衡数的个数。所谓平衡数即有一位做平衡点,左右两边数字的力矩想等。
题解:
枚举平衡点, 然后dp, 注意0参与计算了cnt次, 所以要减去cnt-1.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int key = 9 * 18 * 18;
ll dp[20][20][key*2+10];
int dight[20];
ll dfs(int pos, int mid, int det, bool limit)
{
if(!pos) return det == key;
if(!limit && ~dp[pos][mid][det]) return dp[pos][mid][det];
int up = limit ? dight[pos] : 9;
ll res = 0;
for(int i = 0;i <= up;i ++) {
res += dfs(pos-1, mid, det + (pos-mid) * i, limit && i == dight[pos]);
}
if(!limit) dp[pos][mid][det] = res;
return res;
}
ll solve(ll n)
{
if(n == -1) return 0;
int cnt = 0;
while(n) {
dight[++cnt] = n % 10;
n /= 10;
}
ll res = 0;
for(int i = cnt;i >= 1;i --) {
res += dfs(cnt, i, key, 1);
}
return res - cnt + 1; //0多加了cnt-1次
}
int main()
{
memset(dp, -1, sizeof(dp));
int T;
scanf("%d", &T);
while(T --) {
ll L, R;
scanf("%lld %lld", &L, &R);
printf("%lld\n", solve(R) - solve(L-1) );
}
return 0;
}