2017.10.30闵神讲课DAY3(DP状态压缩)
2017-10-30 09:05
190 查看
DP利用数据结构优化
例题:给定一个集合,从中选出一个最长的等差数列。
集合大小<=5000,数的大小<=10^9.
首先我们可以先想出一个超级暴力的算法,再把它进行优化
先考虑数的大小<=5000的情况。
f[i][j]=f[j][k]+1(a[i]-a[j]=a[j]-a[k]) O(n^3)
用二分查找k可以优化为O(n^2logn)
其实我们只要找他在不在就好,用哈希表即可O(1),我们就把算法优化为O(n^2)了
例题:
给定一个数列,请将他们划分成若干个不相交的区间(这些区间的并集等于整个数列),且每个区间的元素和都非负,求方案数。
n<20?
n<5000?
n<500000?
f[j]=sum(f[j](Si−Sj
4000
>=0))(j<i)
那么如何快速求和呢???
让我们来想想学过的数据结构可以求和的……
线段树!!!!!
线段树可以快速求一个区间的和。
我们将Si,Sj看成下标,那么如果数字很大很大呢 离散化
用线段树进行维护
状态压缩
有时候我们没有办法将已经做过的决策序列S进行简化例题:
一个妹纸说自己刚刚集齐了12星座的前男友,假设她交到每个星座的男朋友的概率都是相等的,求她期望交过的男朋友的个数。
f[S]=1/12*(1+f[S∪{i}])
S是当前已经集齐了S这个集合,i枚举12个星座
但是由于这个问题的高度对称性,不需要状态压缩。
f[i]=i/12*(f[i]+1)+(12-i)/12*(f[i+1]+1)
这个式子经过简化后可得:
f[i]=12/(12-i)+f[i+1]
例题:
一个有n+1个点的平面图(完全图),一个人需要从第0个点出发,设计一条路线使得每个点都经过且只经过一次,且路程最短
n<=20
f[s][j]=minf[s|(1<<j)[j]+dis[i][j]
f[(1<<n)−1][i]=0;
博弈问题
这里指的不是组合游戏问谁有必胜策略的博弈问题。在博弈问题中,因为游戏规则是公平的,所以在相同局面下两个人的决策是相同的,这也就导致了我们选择动态规划解决问题:DP的决策是用相同的策略所以才能写出方程;而且都是想让自己最优而对方最不优,所以博弈问题常常伴随着状态转移方程中max里套min或者min里套max,外层的max或者min是自己的决策,代表在通往所有可能的后继状态中取最优,内层的min或max代表对方的决策,代表对方也要取最优,也就是你的最不优。
例题:
有如下一个双人游戏:N个正整数的序列放在一个游戏平台上,两人轮流从序列的两端取数,取数后该数字被去掉并累加到本玩家的得分中,当数取尽时,游戏结束。以最终得分多者为胜。求最优情况下两个人拿到的数。
N(2 <= N <= 100)
f[l,r]=s[l,r]-min(f[l+1,r],f[l,r-1])
例题:
一个有N枚硬币的堆栈放在地上,从堆顶数起的第i枚硬币的币值为C_i,在每一轮中,当前的玩家至少拿走一枚硬币,至多拿走对手上一次所拿硬币数量的两倍(第一个人第一次只能拿一枚)。当没有硬币可拿时,游戏结束。两个人都想拿更多钱,请问,第一个玩家最多能拿多少钱?
5 <= N <= 2,000,1 <= C_i <= 100,000
f[i][j+1]=s[i]-min{f[i-k][k]}(k<=(j+1)*2)
=max(f[i][j],s[i]-min{f[i-(j*2+1)][j*2+1],f[i-(j*2+2)][j*2+2]}
例题;
A和B玩游戏,一个网格图上有n个帽子和m个带权的硬币,每次A可以翻开一个帽子,B可以在A翻开帽子之前用魔术随意改变这m个硬币的位置,但是必须满足:
硬币必须在帽子下面;每个帽子下面至多有一个硬币;每行每列的帽子数+硬币数为偶数;翻开过的帽子下面的内容不许改变
请问A和B都表现得最好的情况下,A翻到的硬币的价值总和,n≤15。
f[S]=max{min{f[S:i→0],f[S:i→1]+1}}(i未翻开)
无限迭代
一般指状态转移方程中出现循环代值的情况。一般使用某种奇怪的方式解决迭代问题。
当然,大力迭代可能会出奇迹。
例题:
小C和小H玩游戏,每一局小C获胜/平局/失败的概率分别为a/b/c,当小C获胜的场数比小H获胜的场数多n时,小C赢得游戏胜利,当比小H少m时,小H胜利,求小C赢得游戏胜利的概率。
n,m≤100,a+b+c=1
f[i]=a*f[i+1]+b*f[i]+c*f[i-1]
高斯消元
例题:
A和B玩游戏,一共有n张牌,被分给两个人,第i张牌对第张牌的胜率为f[i][j],每轮每个人都等概率地从手牌中随机抽取一张进行对决,胜者获得两张对决的牌,当一个人拥有所有n张牌时获得胜利。共q次询问,求A的起始手牌为S时获胜的概率。
n≤7,f[i][j]+f[j][i]=1。
f[S]=sum{1/(|S|^2)*(p[i][j]*f[S∪{j}]+p[j][i]*f[S-{i}])}
n≤8?f[S]+f[~S]=1。
n≤100?若A∩B=∅,f[A]+[B]=f[A∪B]。
考虑三个人的游戏,f[A]+f[B]+f[C]=1,且对A来说,此处的f[A]=1-f[B∪C]。
相关文章推荐
- 2017.10.30闵神讲课DAY3(DP状态压缩)
- HDOJ 2442 -bricks 六进制状态压缩DP 一直TLE.打表过的..
- hdu4753 状态压缩dp博弈(记忆化搜索写法)
- sgu 225 Little Knights 状态压缩dp
- Hackers’ Crackdown-----UVA11825-----DP+状态压缩
- hdu 1565 方格取数(1) 状态压缩dp
- poj 2411 Mondriaan's Dream(状态压缩DP)
- Uva 10817 - Headmaster's Headache(状态压缩DP)
- 基于连通性状态压缩的动态规划--【插头DP】模板超级详细解释
- HDU2825 Wireless Password(状态压缩DP)
- hdu3001 Travelling 三进制状态压缩dp
- HDU 4336 Card Collector 状态压缩+概率DP
- 2018年全国多校算法寒假训练营练习比赛(第二场) F 德玛西亚万岁(状态压缩DP 未解决)
- hdu1565 dp状态压缩
- poj 3311 floyd+dfs或状态压缩dp 两种方法
- Hdu-1565 方格取数(1) (状态压缩dp入门题
- HDU 1074【状态压缩DP】
- 状态压缩DP题目专辑
- POJ 1143 Number Game 状态压缩dp
- poj 2923 (Relocation)(状态压缩dp)