题解 P1622 释放囚犯
题面
题目描述
Caima 王国中有一个奇怪的监狱,这个监狱一共有 个牢房,这些牢房一字排开,第 个紧挨着第 个(最后一个除外)。现在正好牢房是满的。
上级下发了一个释放名单,要求每天释放名单上的一个人。这可把看守们吓得不轻,因为看守们知道,现在牢房中的 个人,可以相互之间传话。如果某个人离开了,那么原来和这个人能说上话的人,都会很气愤,导致他们那天会一直大吼大叫,搞得看守很头疼。如果给这些要发火的人吃上肉,他们就会安静点。
输入格式
第一行两个整数 和 , 表示释放名单上的人数;
第二行 个整数,表示要释放哪些人,保证按递增的顺序给出。
输出格式
仅一行,表示最少要给多少人次送肉吃。
样例 #1
样例输入 #1
1 | 20 3 |
样例输出 #1
1 | 35 |
提示
样例说明 #1
先释放 号监狱中的罪犯,要给 到 号监狱和 到 号监狱中的 人送肉吃;再释放 号监狱中的罪犯,要给 到 号监狱和 到 号监狱中的 人送肉吃;最后释放 号监狱中的罪犯,要给 到 号监狱和 到 号监狱中的 人送肉吃。
数据规模与约定
- 对于 的数据,,;
- 对于 的数据,,,,保证释放的人所在的牢房编号按递增的顺序给出。
思路
题意即求释放列表中所有罪犯的费用之和最小,每次释放,罪犯i到他两边空牢房之间的所有人,都需要消耗一块肉。每次释放一个罪犯,可以想到区间 DP,状态 f[l][r] 表示从l到r号罪犯全部释放所需要消耗的肉块总数。
之后思考状态转移方程。要求最小值,f[l][r] 初始值 INT_MAX。f[l][r] = min of f[l][m-1] + f[m+1][r] + Pos[r+1] - Pos[l-1] -2 ,其中 m 属于区间 [l,r],枚举合并点,即此次释放的罪犯,罪犯两侧到l和r号罪犯的消耗f[l][m-1]和f[m+1][r]。Pos[i]定义i号罪犯的编号。这里其实是一种反向的思路,m点应该是最先释放的(?Pos[r+1] - Pos[l-1] -2即此区间两侧最近的罪犯之间的人数,减去区间两端。即区间合并的额外费用。注意要在Pos数组中定义Pos[Q+1]=N+1。
代码
1 |
|
小结
本题难点在于建模,区间DP部分比较典型。