关于一个人类智慧的DP - Vijos 1037 搭建双塔

更好的阅读体验戳此进入

(建议您从上方链接进入我的个人网站查看此 Blog,在 Luogu 中图片会被墙掉,部分 Markdown 也会失效)

做这道题的原因是在写 POI 的一道人类智慧题的时候有点想不明白,然后看题解里有人说中间有一步和这道题的思路差不多,于是决定先把这道题做一下。

题面

给你 n 块水晶,每块水晶有一个高度 hi,你可以任选其中一些块,向上叠在一起来搭建两座塔,使得两座塔的高度相同且不为 0,能搭建的话输出最大高度,否则输出 Impossible

1n100,0i=1nhi2000

Vijos-1037 搭建双塔

JDOJ-1222: VIJOS-P1037 搭建双塔

输入格式

n

h1 h2 hn

Examples

Input_1

Output_1

Solution

第一次听说还有这种状态设计

dp(i,j) 表示考虑到第 i 块水晶,能搭建成差值为 j 的两座塔中较高塔的高度,这个东西似乎叫做差值 DP。

我们考虑转移,显然可以分成以下几种情况:

  1. 舍弃这块水晶:dp(i1,j)
  2. 将这块水晶放到较高的塔上:dp(i1,jhi)+hi
  3. 将这块水晶放到较低的塔山,且这样之后两座塔之间的大小关系不变:dp(i1,j+hi)
  4. 将这块水晶放到较低的塔山,且这样之后两座塔之间的大小关系改变:dp(i1,hij)+j

关于第四个方程可以看下面这个图,不难发现有 j=hij,那么 dp(i,j)=dp(i1,j)+j=dp(i1,hij)+j

Vijos-1037-Solution_1.png

所以转移就是上面四个式子求最大值即可。

复杂度 O(nhi)

Code

Code - C++98(JDOJ)

UPD

update-2022_09_27 初稿