【QBXT】学习笔记——Day5dp
2018-01-18 21:09
204 查看
啊,其实应该吧Day4的和Day5放在一起,没有看课表。
今天是考试日,随便写写吧0.0。
rank5拿了一个耳机还是很舒服的23333。
==============分割线===============
不过先讲了一些二进制相关的东西。
刚刚来就是NOI2014起床困难综合征
有n扇门,每扇门后面有一个运算符号xor,or,and,和一个参数t。
一开始可以选择一个不超过m的非负整数,使得经过这n扇门经过运算后数字最大。
n<=100000
0<=m,t<=10^9
每一位是独立的,枚举每一位贪心跑一下就行了。
APIO2015巴厘岛的雕塑
有n棵树,每棵树都有一个年龄,将其分为m组,其中m是介于A~B之间的一个数。
每组至少有一棵树且所选的树是连续的,每棵树一定在某个组中。对于一组,令ai表示该组中树的年龄之和。
合理分配使得ai的按位取或的值最小。
part1:n<=100,1<=A<=B<=n。
part2:n<=2000,A=1,1<=B<=n。
考虑从高位往低位枚举,每一位分别判断。
对于第i位跑一遍dp,看第i位是否能取0,如果不能就是1啦。
然后对于第i-1位,变成一个判定性问题,要在最高位是0情况下跑这一位。
对于part1可以用一个简单的32*n^3dp来做。f[i][j][0/1]表示前i个分成j组,可不可行。枚举断点转移。
对于part2观察到m没有下界,显然若参考part1的想法,我们分到第i位用越少的分组越好。
因此令f[i]为前i个数满足条件分成的最少组数。复杂度32*n^2
BZOJ3900(又是权限题)
题目大意:有n只麋鹿,每只麋鹿有两只角(没有左右之分),重量分别为ai与bi。
每次可以交换任意两只麋鹿的角,问最少经过多少次交换后,
每只麋鹿两只角的重量差不超过c。
数据范围:n<=16
看数据范围想状压,但我根本不会状压啊。
不过还是很好想的,显然答案最多为n-1,如果当i和j两个交换了角,我们就将i和j连边。
那么这样答案一定是一棵树或多棵树。
令f[i]为i这个状态下的最少交换次数。
一个显然的初始值:将i这个状态上的麋鹿的角从小到大排序后,
对于所有偶数j都存在h[j]-h[i]<=c,
则f[i]=sum-1,否则f[i]=inf。其中sum表示i状态下麋鹿的总数。
一种转移:f[i]=min{f[j]+f[i^j]}。
鹰蛋(URAL1223)http://acm.timus.ru/problem.aspx?space=1&num=1223
有M个鹰蛋,N层楼,鹰蛋的硬度是E,也就是说在1~E层楼扔下去不会碎,E+1层楼扔下去会碎。
给定M,N,问至少几次能得到E的具体的值。
①n<=100。
②n<=1000。
③n<=100000。
④n<=1000000。
⑤n<=1000000000。
这个东西是有论文的吧,太繁琐不写在这里了。
51Nod#10子集价值51Nod-1684
新建一个位运算(即给定所有0/1运算后得到0还是1),
求所有非空子集通过这个位运算后的答案的平方和是多少。
n<=5e4
考虑只有和的做法应该怎么做。
枚举每一位,令dp[i][0/1]枚举到第i个数,当前该子集经过一系列位运算后是0/1的方案总数。
那么每一位对答案的贡献就是dp
[1]次。
考虑平方和的意义。
(a1+a2+…+an)^2=a1^2+a2^2+…+an^2+2a1a2+2a1a3+…+2a(n-1)an。
我们发现后面的每一项只与两个未知数有关。
因此可以枚举每两位。
令dp[i][0/1][0/1]表示当前到第i位,这两位的关系分别是0/1与0/1的方案总数。
那么最终对答案的贡献就是dp
[1][1]*2次。
CC-DEVVOTE Devus and their voting system
n个人排成一排投票选总统,要求相邻两个人不能投同样的票,
被投最高的票的人全部当选总统,求期望的总统个数。
n<=36。
这题是n^6logn的,如果没有相邻两个不能投相同票的限制是n^4logn的。
如果考虑前i个人投了多少票和最高票数,那显然复杂度会爆炸,也存不下。
但是我们换个角度,我们在不考虑限制的情况下。
令dp[i][j][k][l]表示考虑了前i个人被投票的情况,
此时最高票是j,共有k个最高票,且有l个人已经投票了。
枚举第i+1个人被几个人投票即可。
由于j*k<=l,时间复杂度为n^4lgn
由于限制的存在,我们在dp状态里再加一维h,表示存在多少对投票是相邻的。
预处理出g[x][y1][z][y2]表示当前有x票,有y1对票在投时是相邻的,
此时我要再投z个票,投完后有y2对在投时是相邻的方案总数。这可以通过枚举以及排列组合算出。
在dp的转移时,我们再枚举第i+1个人被投完后的相邻投票对数即可。
时间复杂度为n^6lgn。常数极小。
这题极其可怕,极其难推,没有听懂,我们还是打表吧。
HDU4352 LIS问题
求l~r的最长上升子序列长度为k的数量。
考虑暴力做,还是用昨天的思想,开一维表示最高位相等还是小于r
dp[i]表示当前以i这个数结尾的最长上升子序列。
那么从前往后枚举每一位,当枚举到数字x,有dp[x]=max{dp[x],dp[0..x-1]+1}。
对于一段区间,我们可以数位dp套dp!
令g[i][j]表示当前到前i位,当前dp的状态是j的方案总数。
枚举第i+1的数是O(10)的,更新j是O(1)的,j共有10^10种可能。
g[i][0/1][0~10][0~10][0~10]…[0~10]=方案总数
表示当前第i位,前面是否有1位小于r,后面是10维,表示当前状态是什么。
就是把里面套的dp的值作为状态来表示出来。
时间复杂度是爆炸的,也存不下。
考虑换状态,(这个f[i]就是后面的10维)
f[i]为以i或比i小结尾的方案数。也就是说这一位会影响比这一位大的所有数的状态。
那么f[i]<=f[i+1]<=f[i]+1
这样我们g[i][0/1][f]的f就是2^11大小的,相当于一个差分。
zhw出的一道类似的题目51Nod1683
dp套dp的题目一般长这样:
有些东西是未知的,要从未知才能推这个东西。
那么我们可以考虑已知这个东西怎么做dp,
然后考虑记下这个dp的状态来乱搞。
51Nod1673又是zhw一道神奇的题
先考虑如果一直每个叶子的相对大小关系,我们可以用贪心解决这个问题。
对于每一个祖先,编号一定大于它的所有儿子。
令f[i]表示i这个状态的节点可以得到的最大乘积,f[i]可以转移到f[i+j],
其中j仅有一个节点,并且节点权值可以算。
令g[i]表示这个状态的节点所有全部向根染色后最终会有多少点被染色。
通过g数组就可以求出权值了。
最大乘积通过转化为对数进行加法运算,避免高精度。
早上的东西后面比较难啊2333,有一些没听懂,以后慢慢学习一下恩。
听zhw说刷1000道bzoj+codeforces的所有div1,就能有NOI金牌水平辣!
一天5道bzoj+2套div1,就能在半年后拿到金牌了(逃)
就这样吧。
第一题是个水题,暴力搜索一下就可以了。
表示15min想出来,15min敲掉,qt和wyl居然没写出来0.0
第二题
考试写了基本分20pt和后面n<=2的30pt,然后后面写挂了。
20pt是直接搜索
另30pt是斯坦纳树的搜索,我们可以枚举一下最后选择的k种颜色是什么。
将这些颜色点作为特殊点,然后dp一下,转移是差不多的。
另30pt也是搜一搜就能过。
满分做法十分玄学,
我们观察到做不了是因为颜色数太多了,如果颜色数只有7种,可以直接斯坦纳树做。
我们将225种颜色,随机分配1~k中的一个数字,
那么7种颜色分配正确的概率大概是0.06,也就是错误率0.994.
那我们用这个做法随机400次,就有0.91的正确率了,
随机600次,正确率高达0.98,当然时限是不一定够的。
第三题
我们考虑有三只兔子,那么中间那只兔子可以向左跳,向右跳。
可以看作这个状态伸出两个儿子分支(造树)。
从外面往里跳的情况是父亲分支。
问题转化为:从节点A出发,经过k条边,到节点B的方案数。
令f[i][j][k]为A点的深度i,A和B的lca深度为j,跳了k步的方案数。
LCA这个东西是可以预处理出来的。
这个东西直接暴力跳一下就行了。
让A和B都不断往上跳100层就可以了!
那么我们的dp就是枚举一下A往哪跳。
f[i][j][k]是可以转移到:
若A不为LCA,则显然不论A往上还是往下,lca都不会变化。
那么我们可以转移到f[i+1][j][k+1]和f[i-1][j][k+1]
若A为LCA,即如果i==j
能转移到f[i+1][j+1][k+1],f[i+1][j][k+1],f[i-1][j-1][k+1]。
第三题的转换问题也是十分玄学,做题太少辣。
莫非真的要开始猛刷了嘛。但是刷不动啊。
溜了溜了,明天讲树上问题,点分治不大熟悉了0.0
感觉复习一波。
今天是考试日,随便写写吧0.0。
rank5拿了一个耳机还是很舒服的23333。
==============分割线===============
Day5 1.18AM
上午依旧讲dp不过先讲了一些二进制相关的东西。
刚刚来就是NOI2014起床困难综合征
有n扇门,每扇门后面有一个运算符号xor,or,and,和一个参数t。
一开始可以选择一个不超过m的非负整数,使得经过这n扇门经过运算后数字最大。
n<=100000
0<=m,t<=10^9
每一位是独立的,枚举每一位贪心跑一下就行了。
APIO2015巴厘岛的雕塑
有n棵树,每棵树都有一个年龄,将其分为m组,其中m是介于A~B之间的一个数。
每组至少有一棵树且所选的树是连续的,每棵树一定在某个组中。对于一组,令ai表示该组中树的年龄之和。
合理分配使得ai的按位取或的值最小。
part1:n<=100,1<=A<=B<=n。
part2:n<=2000,A=1,1<=B<=n。
考虑从高位往低位枚举,每一位分别判断。
对于第i位跑一遍dp,看第i位是否能取0,如果不能就是1啦。
然后对于第i-1位,变成一个判定性问题,要在最高位是0情况下跑这一位。
对于part1可以用一个简单的32*n^3dp来做。f[i][j][0/1]表示前i个分成j组,可不可行。枚举断点转移。
对于part2观察到m没有下界,显然若参考part1的想法,我们分到第i位用越少的分组越好。
因此令f[i]为前i个数满足条件分成的最少组数。复杂度32*n^2
BZOJ3900(又是权限题)
题目大意:有n只麋鹿,每只麋鹿有两只角(没有左右之分),重量分别为ai与bi。
每次可以交换任意两只麋鹿的角,问最少经过多少次交换后,
每只麋鹿两只角的重量差不超过c。
数据范围:n<=16
看数据范围想状压,但我根本不会状压啊。
不过还是很好想的,显然答案最多为n-1,如果当i和j两个交换了角,我们就将i和j连边。
那么这样答案一定是一棵树或多棵树。
令f[i]为i这个状态下的最少交换次数。
一个显然的初始值:将i这个状态上的麋鹿的角从小到大排序后,
对于所有偶数j都存在h[j]-h[i]<=c,
则f[i]=sum-1,否则f[i]=inf。其中sum表示i状态下麋鹿的总数。
一种转移:f[i]=min{f[j]+f[i^j]}。
鹰蛋(URAL1223)http://acm.timus.ru/problem.aspx?space=1&num=1223
有M个鹰蛋,N层楼,鹰蛋的硬度是E,也就是说在1~E层楼扔下去不会碎,E+1层楼扔下去会碎。
给定M,N,问至少几次能得到E的具体的值。
①n<=100。
②n<=1000。
③n<=100000。
④n<=1000000。
⑤n<=1000000000。
这个东西是有论文的吧,太繁琐不写在这里了。
51Nod#10子集价值51Nod-1684
新建一个位运算(即给定所有0/1运算后得到0还是1),
求所有非空子集通过这个位运算后的答案的平方和是多少。
n<=5e4
考虑只有和的做法应该怎么做。
枚举每一位,令dp[i][0/1]枚举到第i个数,当前该子集经过一系列位运算后是0/1的方案总数。
那么每一位对答案的贡献就是dp
[1]次。
考虑平方和的意义。
(a1+a2+…+an)^2=a1^2+a2^2+…+an^2+2a1a2+2a1a3+…+2a(n-1)an。
我们发现后面的每一项只与两个未知数有关。
因此可以枚举每两位。
令dp[i][0/1][0/1]表示当前到第i位,这两位的关系分别是0/1与0/1的方案总数。
那么最终对答案的贡献就是dp
[1][1]*2次。
CC-DEVVOTE Devus and their voting system
n个人排成一排投票选总统,要求相邻两个人不能投同样的票,
被投最高的票的人全部当选总统,求期望的总统个数。
n<=36。
这题是n^6logn的,如果没有相邻两个不能投相同票的限制是n^4logn的。
如果考虑前i个人投了多少票和最高票数,那显然复杂度会爆炸,也存不下。
但是我们换个角度,我们在不考虑限制的情况下。
令dp[i][j][k][l]表示考虑了前i个人被投票的情况,
此时最高票是j,共有k个最高票,且有l个人已经投票了。
枚举第i+1个人被几个人投票即可。
由于j*k<=l,时间复杂度为n^4lgn
由于限制的存在,我们在dp状态里再加一维h,表示存在多少对投票是相邻的。
预处理出g[x][y1][z][y2]表示当前有x票,有y1对票在投时是相邻的,
此时我要再投z个票,投完后有y2对在投时是相邻的方案总数。这可以通过枚举以及排列组合算出。
在dp的转移时,我们再枚举第i+1个人被投完后的相邻投票对数即可。
时间复杂度为n^6lgn。常数极小。
这题极其可怕,极其难推,没有听懂,我们还是打表吧。
HDU4352 LIS问题
求l~r的最长上升子序列长度为k的数量。
考虑暴力做,还是用昨天的思想,开一维表示最高位相等还是小于r
dp[i]表示当前以i这个数结尾的最长上升子序列。
那么从前往后枚举每一位,当枚举到数字x,有dp[x]=max{dp[x],dp[0..x-1]+1}。
对于一段区间,我们可以数位dp套dp!
令g[i][j]表示当前到前i位,当前dp的状态是j的方案总数。
枚举第i+1的数是O(10)的,更新j是O(1)的,j共有10^10种可能。
g[i][0/1][0~10][0~10][0~10]…[0~10]=方案总数
表示当前第i位,前面是否有1位小于r,后面是10维,表示当前状态是什么。
就是把里面套的dp的值作为状态来表示出来。
时间复杂度是爆炸的,也存不下。
考虑换状态,(这个f[i]就是后面的10维)
f[i]为以i或比i小结尾的方案数。也就是说这一位会影响比这一位大的所有数的状态。
那么f[i]<=f[i+1]<=f[i]+1
这样我们g[i][0/1][f]的f就是2^11大小的,相当于一个差分。
zhw出的一道类似的题目51Nod1683
dp套dp的题目一般长这样:
有些东西是未知的,要从未知才能推这个东西。
那么我们可以考虑已知这个东西怎么做dp,
然后考虑记下这个dp的状态来乱搞。
51Nod1673又是zhw一道神奇的题
先考虑如果一直每个叶子的相对大小关系,我们可以用贪心解决这个问题。
对于每一个祖先,编号一定大于它的所有儿子。
令f[i]表示i这个状态的节点可以得到的最大乘积,f[i]可以转移到f[i+j],
其中j仅有一个节点,并且节点权值可以算。
令g[i]表示这个状态的节点所有全部向根染色后最终会有多少点被染色。
通过g数组就可以求出权值了。
最大乘积通过转化为对数进行加法运算,避免高精度。
早上的东西后面比较难啊2333,有一些没听懂,以后慢慢学习一下恩。
听zhw说刷1000道bzoj+codeforces的所有div1,就能有NOI金牌水平辣!
一天5道bzoj+2套div1,就能在半年后拿到金牌了(逃)
就这样吧。
Day5 1.18Night
晚上评讲考试,题目不放在这里233.第一题是个水题,暴力搜索一下就可以了。
表示15min想出来,15min敲掉,qt和wyl居然没写出来0.0
第二题
考试写了基本分20pt和后面n<=2的30pt,然后后面写挂了。
20pt是直接搜索
另30pt是斯坦纳树的搜索,我们可以枚举一下最后选择的k种颜色是什么。
将这些颜色点作为特殊点,然后dp一下,转移是差不多的。
另30pt也是搜一搜就能过。
满分做法十分玄学,
我们观察到做不了是因为颜色数太多了,如果颜色数只有7种,可以直接斯坦纳树做。
我们将225种颜色,随机分配1~k中的一个数字,
那么7种颜色分配正确的概率大概是0.06,也就是错误率0.994.
那我们用这个做法随机400次,就有0.91的正确率了,
随机600次,正确率高达0.98,当然时限是不一定够的。
第三题
我们考虑有三只兔子,那么中间那只兔子可以向左跳,向右跳。
可以看作这个状态伸出两个儿子分支(造树)。
从外面往里跳的情况是父亲分支。
问题转化为:从节点A出发,经过k条边,到节点B的方案数。
令f[i][j][k]为A点的深度i,A和B的lca深度为j,跳了k步的方案数。
LCA这个东西是可以预处理出来的。
这个东西直接暴力跳一下就行了。
让A和B都不断往上跳100层就可以了!
那么我们的dp就是枚举一下A往哪跳。
f[i][j][k]是可以转移到:
若A不为LCA,则显然不论A往上还是往下,lca都不会变化。
那么我们可以转移到f[i+1][j][k+1]和f[i-1][j][k+1]
若A为LCA,即如果i==j
能转移到f[i+1][j+1][k+1],f[i+1][j][k+1],f[i-1][j-1][k+1]。
第三题的转换问题也是十分玄学,做题太少辣。
莫非真的要开始猛刷了嘛。但是刷不动啊。
溜了溜了,明天讲树上问题,点分治不大熟悉了0.0
感觉复习一波。
相关文章推荐
- 【QBXT】学习笔记——Day14非传统题
- 【QBXT】学习笔记——Day7分块
- 【QBXT】学习笔记——Day6树上问题
- 【QBXT】学习笔记——Day12杂题
- 【QBXT】学习笔记——Day8分治
- 【QBXT】学习笔记——Day10数学
- 【QBXT】学习笔记——Day11网络流
- 【QBXT】学习笔记——Day9数学
- 【QBXT】学习笔记——Day1/2数据结构
- 【QBXT】学习笔记——Day13计算几何
- 【QBXT】学习笔记——Day3/4图论+dp
- QBXT DAY 2 笔记
- 【转载】学习笔记之 IIS 安全 / 数字证书 / SSL 原理
- SqlServer 2005 T-SQL Query 学习笔记(4)
- Think in java4 几个误区--学习笔记1
- Excel VBA 学习笔记(陆续更新)
- (原创)c#学习笔记04--流程控制01--布尔逻辑01--布尔赋值运算符
- R语言连接Mysql数据库的步骤及简单使用(学习笔记)
- SQL server 2005 学习笔记 (1)
- hibernate学习笔记--入门