数位DP 计划

通常的数位dp可以写成如下形式:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. int dfs(int i, int s, bool e) {  
  2.     if (i==-1) return s==target_s;  
  3.     if (!e && ~f[i][s]) return f[i][s];  
  4.     int res = 0;  
  5.     int u = e?num[i]:9;  
  6.     for (int d = first?1:0; d <= u; ++d)  
  7.         res += dfs(i-1, new_s(s, d), e&&d==u);  
  8.     return e?res:f[i][s]=res;  
  9. }  

其中:

f为记忆化数组;

i为当前处理串的第i位(权重表示法,也即后面剩下i+1位待填数);

s为之前数字的状态(如果要求后面的数满足什么状态,也可以再记一个目标状态t之类,for的时候枚举下t);

e表示之前的数是否是上界的前缀(即后面的数能否任意填)。

for循环枚举数字时,要注意是否能枚举0,以及0对于状态的影响,有的题目前导0和中间的0是等价的,但有的不是,对于后者可以在dfs时再加一个状态变量z,表示前面是否全部是前导0,也可以看是否是首位,然后外面统计时候枚举一下位数。It depends.

注意:

不满足区间减法性质的话(如hdu 4376),不能用solve(r)-solve(l-1),状态设计会更加诡异。

刷题目录:

hdu2089 不要62

Hdu3555不能出现连续的49

HDU 3652 出现13,而且能被13整除。

HDU 3709 平衡数

light OJ 1140两个数之间的所有数中零的个数。

lightoj 1032  二进制数中连续两个‘1’出现次数的和

Codeforces 55D. Beautiful numbers

POJ 3252  Round Number (组合数)

LightOJ 1068 能被K整数且各位数字之和也能被K整除的数

LightOJ1205求区间[a,b]的回文数个数。

hdu3886求满足符号串的数字个数。

HDU4352严格上升子序列的长度为K的个数。

ural 1057 数位统计

codeforces215E周期数

codeforces258B在1-m中任选7个数,要使前六个数字中的“4”,"7"之和小于第七个的,

HDU4507 和7无关数的平方和

Zoj2599 数位统计(见题意)

zoj3162分形、自相似

ZOJ3494 BCD Code(AC自动机+数位DP)

posted @ 2016-02-14 19:03  luckycode  阅读(306)  评论(0编辑  收藏  举报