[解决] 01背包的分堆变形题

楼主: fatcat8127 (胖胖猫)   2020-10-08 16:36:02
先上题目:e900:交换纸牌游戏
https://zerojudge.tw/ShowProblem?problemid=e900
题目要求和01背包的变形问题-分堆一样,要求分成两堆且数字和越接近越好。
但这个题目多了限制就是在最少的翻牌次数...。
这边提供通过的程式码:https://ideone.com/qQ5iL5
问题差异:
选某张卡片正面的点数时是加上差值且翻牌次数不变,否则必定选择反面,
加上“负的差值”且次数多一,分堆问题时只要考虑选不选某个数字,
不选时状态不变,但这题不选时因为加上“负的差值”状态会改变。
状态设定:
状态改变时会有负数,阵列不能存取负的位置所以需要做偏移,
最糟糕的情况=负最多时,每张牌的范围是(-12,12),牌数最多1000张,
总和=(-12000,12000) ... 阵列的空间要求。
base(偏移量)=所有牌的负值总和。
初始状态:用到的数字=0(做完偏移后是 base)且该状态下翻牌次数=0
cnt[ 目前使用的阵列 ][ 偏移后的数字 ]= 最少的翻牌次数
状态转移:
根据第i张牌,只需更新 pvt (上一次有纪录到的数字),避免重复纪录这一次更新
到的状态,只要检查该格位置是否第一次更新。
不翻:v(新状态)=pvt+num[0][i]-num[1][i]且 翻牌次数不变
cnt[now][v]=min(cnt[now][v],cnt[pre][pvt])
翻牌:v(新状态)=pvt+num[1][i]-num[0][i]且 翻牌次数多一
cnt[now][v]=min(cnt[now][v],cnt[pre][pvt]+1)
输出时从两堆差值=0,1(-1 or 1)... 依此类推直到找到第1个次数的状态不是
INF 就是答案。
作者: ucrxzero (RX-0)   2020-10-18 18:19:00
请问这比leetcode难吗
作者: ddavid (谎言接线生)   2020-10-21 09:06:00
leetcode有简单题也有难题,楼上你想问什么
作者: ucrxzero (RX-0)   2020-10-21 10:29:00
找工作需要写这个吗
作者: ddavid (谎言接线生)   2020-10-21 13:34:00
看你找什么工作,还有算法题从来就不只是为了让你背题到时工作解一模一样的问题到时工作你不会直接看到背包问题,却会用到解题思维以及动态规划、greedy、divide and conquer、tree、graph等等概念,写算法题是为了让你懂得怎么自己思考应用这些概念当然你可找个用不上解题思维的工作,但这个版就是解题版XD看到你在别的版也问过leetcode的问题,也许我在Python以前这篇抛砖的文章可以给你一点参考?XD #1UQl27Mt (Python)
作者: ucrxzero (RX-0)   2020-10-30 20:53:00
OK

Links booklink

Contact Us: admin [ a t ] ucptt.com