您的位置:首页 > 其它

HDU 3709 Balanced Number(数位dp)

2015-12-07 16:45 435 查看
题意:若某数,固定某位为支点,得到平衡的则称为平衡数。给定区间问有多少个。

思路:数位dp。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
using namespace std;

typedef long long LL;
#define mem(a, n) memset(a, n, sizeof(a))
#define ALL(v) v.begin(), v.end()
#define si(a) scanf("%d", &a)
#define sii(a, b) scanf("%d%d", &a, &b)
#define siii(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pb push_back
#define eps 1e-8
const int inf = 0x3f3f3f3f, N = 2e3 + 5, MOD = 1e9 + 7;

int T, cas = 0;
int n, m;
LL l, r;
int bit[20];
LL dp[20][20]
;

LL dfs(int pos, int o, int l, bool flag) {
if(pos == -1) return l == 0;
if(l < 0) return 0;
if(dp[pos][o][l] != -1 && !flag) return dp[pos][o][l];
LL ret = 0;
int ed = flag ? bit[pos] : 9;
for(int i = 0; i <= ed; i ++) {
int nxt = l;
nxt += (pos - o) * i;
ret += dfs(pos - 1, o, nxt, flag && i == ed);
}
if(!flag) dp[pos][o][l] = ret;
return ret;
}

LL cal(LL x) {
int len = 0;
while(x) {
bit[len ++] = x % 10;
x /= 10;
}
LL ret = 0;
for(int i = 0; i < len; i ++)
ret += dfs(len - 1, i, 0, 1);
return ret - (len - 1);
}

int main(){
#ifdef LOCAL
freopen("/Users/apple/input.txt", "r", stdin);
//	freopen("/Users/apple/out.txt", "w", stdout);
#endif

si(T);
mem(dp, -1);
while(T --) {
scanf("%lld%lld", &l, &r);
printf("%lld\n", cal(r) - cal(l - 1));
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: