题解 P1622 释放囚犯
题面
题目描述
Caima 王国中有一个奇怪的监狱,这个监狱一共有 $P$ 个牢房,这些牢房一字排开,第 $i$ 个紧挨着第 $i+1$ 个(最后一个除外)。现在正好牢房是满的。
上级下发了一个释放名单,要求每天释放名单上的一个人。这可把看守们吓得不轻,因为看守们知道,现在牢房中的 $P$ 个人,可以相互之间传话。如果某个人离开了,那么原来和这个人能说上话的人,都会很气愤,导致他们那天会一直大吼大叫,搞得看守很头疼。如果给这些要发火的人吃上肉,他们就会安静点。
输入格式
第一行两个整数 $P$ 和 $Q$,$Q$ 表示释放名单上的人数;
第二行 $Q$ 个整数,表示要释放哪些人,保证按递增的顺序给出。
输出格式
仅一行,表示最少要给多少人次送肉吃。
样例 #1
样例输入 #1
1 | 20 3 |
样例输出 #1
1 | 35 |
提示
样例说明 #1
先释放 $14$ 号监狱中的罪犯,要给 $1$ 到 $13$ 号监狱和 $15$ 到 $20$ 号监狱中的 $19$ 人送肉吃;再释放 $6$ 号监狱中的罪犯,要给 $1$ 到 $5$ 号监狱和 $7$ 到 $13$ 号监狱中的 $12$ 人送肉吃;最后释放 $3$ 号监狱中的罪犯,要给 $1$ 到 $2$ 号监狱和 $4$ 到 $5$ 号监狱中的 $4$ 人送肉吃。
数据规模与约定
- 对于 $50\%$ 的数据,$1 \le P \le 100$,$1 \le Q \le 5$;
- 对于 $100\%$ 的数据,$1 \le P \le 10^3$,$1 \le Q \le 100$,$Q \le P$,保证释放的人所在的牢房编号按递增的顺序给出。
思路
题意即求释放列表中所有罪犯的费用之和最小,每次释放,罪犯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部分比较典型。