bzoj3900 交換茸角(狀壓DP)

2021-09-26 07:29:06 字數 860 閱讀 9969

神題一道,入手毫無思路

還是頭一次寫這種找下界的狀壓dp,首先,n頭路,我們的最大交換次數為n-1次

因為把所有鹿的茸角打亂重新分配的話,只需要n-1次就可按照從小到大的順序完成重排

這也是差值最小的方法,但是如果這樣都不合法的話,說明這個集合沒法重排,輸出-1

好了,那麼說說怎麼優化

對於每乙個集合,只要他可以重排,我們就可以通過∣s∣

|s|∣s

∣-1的次數完成重排,那麼,分成的集合越多,我們所積累的-1也更多,雖然∑i∈

s∣i∣

==

n\sum_|i|==n

∑i∈s​∣

i∣==

n但是我們這是統計的答案卻是n−n-

n−集合數,w我們就達到了最小化的目的

#include

#include

#include

#include

#include

#include

using

namespace std;

const

int maxn =17;

struct node

deer[maxn]

;int f[

1<<18]

,n,c,aa[maxn*10]

;int

check

(int s)

intmain()

for(

int i=

1;i)f[i]

=check

(i);

for(

int i=

1;i<=maxx;i++)}

cout<;

bzoj3900 交換茸角

dp i 表示讓狀態為i的鹿滿足要求的最少交換次數 不能列舉兩頭鹿交換,因為一頭鹿可能交換多次後轉移到下乙個狀態 那就列舉子集 dp i min 初始化 將i這個狀態上的麋鹿的角從小到大排序後,若相鄰的i和i 1滿足 h i 1 h i c,則dp i 鹿的個數 1,否則dp i inf 因為若有t...

bzoj3900 交換茸角

題目鏈結 看到n比較小,可以狀壓。可以先考慮什麼情況下會無法平衡。顯然就是排完序之後兩兩相鄰的不能滿足小於等於c的限制。狀態。用f i 來表示i集合中的鹿完成交換所需要的次數。預處理。無法平衡的肯定就是inf。已經平衡的是0。其他的先暫設為k 1 k是i集合中鹿的個數 然後轉移。每個集合可以由他的子...

3900 交換茸角

time limit 20 sec memory limit 512 mb submit 165 solved 72 submit status discuss 動物園裡有 n 頭麋鹿。每頭麋鹿有兩支茸角,每支茸角有乙個重量。然而,一旦某頭麋鹿上 兩支茸角的重量之差過大,這頭麋鹿就會失去平衡摔倒。為...