排座位&&Little Elephant And Permutation——排列dp的处理

排列的问题,就是要把序列排个序,使之达到某种最优值或者统计方案数

dp可以解决部分排列问题。

通常的解决方案是,按照编号(优先级)排序决策,从左到右决策两种。

这里主要是第一个。

 

排座位
• 有 𝑛 个人坐成一排
• 对于相邻两个人 𝑖, 𝑗
• 如果 𝑖 < 𝑗,则会产生 𝑎𝑖 + 𝑏𝑗 的愉悦度
• 否则会产生 𝑐𝑖 + 𝑑𝑗 的愉悦度
• 求一个排列让最大化愉悦度
• 𝑛 ≤ 3000

从左到右决策,肯定就要状压了。

但是可以发现,我们并不关心一个i左右是谁,只关心编号和i的相对大小。

而且,这个贡献ai,bj,ci,dj是可以独立的。

思路就比较自然了。

我们按照编号从小到大决策。

每个点i的放置有几种:

1.左右都比i小。

2/3.左/右比i大。

4.左右都比i大。

 

但是麻烦的是,如果直接dp可能最后形成不了一个序列。

不是一个整段。

所以,还要引入段的概念。

 

i的决策是:

1.左右都比i小,即连接之前的两个段。

2/3.左/右比i大,另一个比i小,即连接一个段。

4.左右都比i大,即i自成一段。

每种中,i对答案的贡献可以现场统计。

因为,我们的编号是从小到大处理的,

如果我们能够正确连接的话,这个贡献一定是可以算上的。

 

f[i][j]表示,处理完前编号i个,形成了j段的方案数。

 

还有一个问题是,边界情况,没有左/右,没有这个贡献。

那么可以f[i][j][0/1][0/1]表示是否放了最左边最右边的。

答案:f[n][1][1][1]

 

 

Solution :

假定ai是一个1~n的数列。

对于合法的bi数列,乘上n!就是所有的ai和bi的情况了。

 

这样,贡献就比较好统计了。

dp[i][j][k]表示,处理bi中前i个位置,有j个是空的,贡献是k的方案数。

看这篇题解:

【做题】TCSRM592 Div1 500 LittleElephantAndPermutationDiv1——计数&dp

 

其实还有一个题:(虽然不是dp)

有趣的家庭菜园

posted @ 2018-10-06 20:32  *Miracle*  阅读(295)  评论(0编辑  收藏  举报