HDU2089(数位dp)

喜闻乐见的数位入门第一道,这个dp[pos][state]记录的是第pos位如果没有限制的话(有限制当然要搜一搜暴力数了),前一位 放6 or 不放6 的方案数。也就是并不是要求的答案,其实就是记忆化一下,减小搜索的复杂度,跟dp没啥关系吧……

 

 1 int n, m, cnt;
 2 ll a[10], dp[10][2];
 3 
 4 ll dfs(int pos, int pre, int state, int limit) {
 5     if (!pos)   return 1;
 6     if (!limit && dp[pos][state] >= 0)  return dp[pos][state];
 7 
 8     int up = limit ? a[pos] : 9;
 9     ll ret = 0;
10     rep(i, 0, up) {
11         if (i == 4 || (pre == 6 && i == 2)) continue;
12         ret += dfs(pos - 1, i, i == 6, limit & (i == a[pos]));
13     }
14 
15     if (!limit) dp[pos][state] = ret;
16     return ret;
17 }
18 
19 ll solve(int x) {
20     for (cnt = 0; x; x /= 10)
21         a[++cnt] = x % 10;
22     return dfs(cnt, -1, 0, 1);
23 }
24 
25 int main() {
26     init(dp, -1);
27     while (~scanf("%d %d", &n, &m) && (n | m)) {
28         writeln(solve(m) - solve(n - 1));
29     }
30     return 0;
31 }

 

转载于:https://www.cnblogs.com/AlphaWA/p/10647748.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值