B(多阶段dp)
大致题意:有若干个任务,有x、t、y、r四个属性(y<=x,r<=t),有两个阶段,到达第一阶段需要s1经验值,到达第二阶段需要s2经验值,任务属性中,x表示在到达第一阶段前完成该任务所奖励的经验值,y表示在到达第一阶段后完成该任务所奖励的经验值,t表示在在到达第一阶段前完成该任务所花费的时间,r表示在到达第一阶段后完成该任务所花费的时间,先求到达第二阶段需要花费的最少时间
题解:最少时间+二维变量,一看很像背包,但两个阶段所需经验不同、任务数完成情况繁多,明显无法用背包来维护状态
故用dp[i][j]来表示状态,表示第一阶段前所获经验值=i,第一阶段后所获经验值=j时,所花费的最少时间
则dp[i][j]=min{dp[i][j],dp[i-a[k].x][j]+a[k].t,dp[i][j-a[k].y]+a[k].r}(即分别考虑第k个任务是在第一阶段前还是第一阶段后完成还是不完成,取最小值)
细节:任务的处理顺序—若不是从按x的从小到大顺序,会有什么问题?
在同一个阶段内状态转移时,类似于背包,任务的顺序不会产生影响,而overflow时,任务的顺序会产生影响
假设最佳方案时第一阶段的完成任务,按其x值递增排列是(1,2,3,4,5,6),任务6完成第一阶段并将部分经验值转移到第二阶段,前5个任务随意打乱顺序都不会影响结果(都不会完成第一阶段,相当于一个类似背包的普通dp),但如果将第6个任务提前,比如(6,5,4,3,2,1),有可能提前完成第一阶段而导致不是最佳结果。
故将任务按x的顺序从小到大排,确保第一阶段完成前任务的完成顺序按递增顺序排列
下列代码根据j、k的情况分三类讨论:
- j<=s1,不会overflow,按正常dp方程处理
- j大于s1,此时会发生overflow,k需减去第一阶段转移来的多余值
- k不存在跨阶段问题,故按普通dp方程处理
1 | #include <algorithm> |
《关于我因为数组大小没开对wa了半天这件事》
F(博弈论+图论+树上问题)
大致题意:给定一颗树,在树上进行游戏,游戏规则如下:
- A可选定一个节点作为chip出发点,之后由B开始游戏
- 当轮到本人操作时,可选择将chip移至当前节点的子节点或父节点处(即与之相邻的节点),但同一节点不能多次到达,若无法继续移动,则判本人负
题解:
在场上想的是所有的路径只能分为3类,只上、只下和先上后下,如果只下很容易处理,套用博弈论中的必胜点和必输点+树形dp就行,只上的情况根据每个节点的深度也可得出,但先上后下的情况过于复杂
引入图论中完全匹配的概念:
- 完全匹配是数量最多的一组边集,满足每条边的左右节点都只出现一次
- 若所有节点都在该边集出现过一次,则称该图完美匹配
将树看成图,结论:若图是完美匹配图,则Bob必胜,否则Alice必胜
证明如下:
- 若图是完美匹配图,则可将所有点划分成(s1,s2),(s3,s4)…若干个二元组,则当Alice选定任意个节点,Bob都可将其移动到其对应节点上,由于不能多次到达同一节点,Alice只能选择其他二元组的节点,Bob仍可重复上述操作直至所有节点都被遍历完毕,Bob胜利
- 若图不是完美匹配,设存在最大匹配(s1,s2),(s3,s4)…若干个二元组,有t个点不在该点集内,则Alice可选择不在该点集内的点开始游戏,Bob只能移动到该点集内的一个点(否则两个不在点集内的点也能匹配,与最大匹配相悖),此时Alice可重复1中Bob操作,Bob输。若Bob可移动到不在该点集内的点,注意,,一开始时通过一个集外节点进入匹配点集,若再次从匹配点集到达集外节点,可将二元组重新分配且匹配数+1(画个图就很好理解),与最大匹配定义相悖。
按正常图的方法求最大匹配,时间复杂度过大,而本题是特殊的树形结构,运用树形dp可在O(n)内求出任意子树的最大匹配情况
1 |
|
dp[i]表示以i为根的子树其不匹配的点数量,为0表示该子树完美匹配
今天被博弈论爆打的教训:1.不要纠结于每个人如何作出最佳操作,有时候只看结果思路更简单;2.图和博弈论可以根据完美匹配的定义结合,多留意一下
E
坑位预定