[转]数位dp小记
2015-06-09 16:14
260 查看
转载自:http://blog.csdn.net/guognib/article/details/25472879
参考:
http://www.cnblogs.com/jffifa/archive/2012/08/17/2644847.html
kuangbin :http://www.cnblogs.com/kuangbin/category/476047.html
http://blog.csdn.net/cmonkey_cfj/article/details/7798809
http://blog.csdn.net/liuqiyao_01/article/details/9109419
数位dp有递推和记忆化搜索的方法,比较来说记忆化搜索方法更好。通过博客一的一个好的模板,数位dp就几乎变成一个线性dp问题了。
下为博客一内容:
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
偷看了下7k+大牛的数位统计dp写法,通常的数位dp可以写成如下形式:
其中:
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),状态设计会更加诡异。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
正如上面说的要注意:
前导零是否有影响。
是否满足区间减的性质。(如hdu4376,还没做,先记上)
几乎就是模板题:
模板:
UESTC 1307相邻的数差大于等于2
(不允许有前导0,前导0对计算有影响,注意前导0的处理)
View Code
!!!是比较不错,待看的题
比较还好的处理的题目:
Codeforces 55D Beautiful numbers!!!
spoj 10606 Balanced Numbers
ac自动机和数位dp结合(!!!):
hdu4376!!!(区间不可减???)
ZOJ3494 BCD Code(AC自动机+数位DP)!!!
整除和简单统计:
HDU4507 和7无关数的平方和!!!
HDU 3652 出现13,而且能被13整除
LightOJ 1068 能被K整数且各位数字之和也能被K整除的数
light OJ 1140两个数之间的所有数中零的个数。
lightoj 1032 二进制数中连续两个‘1’出现次数的和
其它:
LightOJ1205求区间[a,b]的回文数个数。
ural 1057 数位统计
codeforces215E周期数
codeforces258B在1-m中任选7个数,要使前六个数字中的“4”,"7"之和小于第七个的,
Zoj2599 数位统计(见题意)
zoj3162分形、自相似
参考:
http://www.cnblogs.com/jffifa/archive/2012/08/17/2644847.html
kuangbin :http://www.cnblogs.com/kuangbin/category/476047.html
http://blog.csdn.net/cmonkey_cfj/article/details/7798809
http://blog.csdn.net/liuqiyao_01/article/details/9109419
数位dp有递推和记忆化搜索的方法,比较来说记忆化搜索方法更好。通过博客一的一个好的模板,数位dp就几乎变成一个线性dp问题了。
下为博客一内容:
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
偷看了下7k+大牛的数位统计dp写法,通常的数位dp可以写成如下形式:
int dfs(int i, int s, bool e) { if (i==-1) return s==target_s; if (!e && ~f[i][s]) return f[i][s]; int res = 0; int u = e?num[i]:9; for (int d = first?1:0; d <= u; ++d) res += dfs(i-1, new_s(s, d), e&&d==u); return e?res:f[i][s]=res; }
其中:
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),状态设计会更加诡异。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
正如上面说的要注意:
前导零是否有影响。
是否满足区间减的性质。(如hdu4376,还没做,先记上)
几乎就是模板题:
模板:
UESTC 1307相邻的数差大于等于2
(不允许有前导0,前导0对计算有影响,注意前导0的处理)
LL dp[25][1 << 11][11]; int bit[25]; int k; int getnews(int s, int x) { for(int i=x;i<10;i++) if(s&(1<<i))return (s^(1<<i))|(1<<x); return s|(1<<x); } int getnum(int s) { int ret = 0; while (s) { if (s & 1) ret++; s >>= 1; } return ret; } LL dfs(int pos, int s, int e, int z) { if (pos == -1) return getnum(s) == k; if (!e && ~dp[pos][s][k]) return dp[pos][s][k]; int end = e ? bit[pos] : 9; LL ans = 0; for (int i = 0; i <= end; i++) { int news = getnews(s, i); if (z && !i) news = 0; ans += dfs(pos - 1, news, e && (i == end), z && (!i)); } if (!e) dp[pos][s][k] = ans; return ans; } LL calc(LL n) { int len = 0; while (n) { bit[len++] = n % 10; n /= 10; } return dfs(len - 1, 0, 1, 1); } int main () { LL n, m; memset(dp, -1, sizeof(dp)); int t; scanf("%d", &t); int nc = 1; while (t--) { cin >> n >> m >> k; printf("Case #%d: ", nc++); cout << calc(m) - calc(n - 1) << endl; } return 0; }
View Code
!!!是比较不错,待看的题
比较还好的处理的题目:
Codeforces 55D Beautiful numbers!!!
spoj 10606 Balanced Numbers
ac自动机和数位dp结合(!!!):
hdu4376!!!(区间不可减???)
ZOJ3494 BCD Code(AC自动机+数位DP)!!!
整除和简单统计:
HDU4507 和7无关数的平方和!!!
HDU 3652 出现13,而且能被13整除
LightOJ 1068 能被K整数且各位数字之和也能被K整除的数
light OJ 1140两个数之间的所有数中零的个数。
lightoj 1032 二进制数中连续两个‘1’出现次数的和
其它:
LightOJ1205求区间[a,b]的回文数个数。
ural 1057 数位统计
codeforces215E周期数
codeforces258B在1-m中任选7个数,要使前六个数字中的“4”,"7"之和小于第七个的,
Zoj2599 数位统计(见题意)
zoj3162分形、自相似
相关文章推荐
- serialVersionUID行动
- 我所了解的javaScript细节
- C语言 链表反向打印与反转
- PHP中超全局变量$GLOBALS和global的区别
- 在Activity中使用Fragment需要先集成FragmentActivity
- java Thread state 分析
- Android的PopupWindow使用android学习之旅(四十三)
- android中image文件的压缩与解压缩
- Android的PopupWindow使用android学习之旅(四十三)
- Android的PopupWindow使用android学习之旅(四十三)
- mysql中You can't specify target table for update in FROM clause错误
- 一---Android-SDK系列文章(6) ---JAVA 程序&& android应用程序(main函数)
- java 根据经纬度获取地址
- XmlParser和HtmlParser
- 流程自动化布局
- 隐马尔科夫学习六(四)
- Android 通话:后台通话过程中锁屏解锁,发现听筒内存在锁屏提示音
- 2015.6.9日 电话面试(亚信科技)
- 大话数据结构—顺序表、有序表、线性索引查找
- Object-C-NSFileHandle