bzoj3900 交換茸角

2022-03-01 21:07:43 字數 810 閱讀 1898

dp[i]表示讓狀態為i的鹿滿足要求的最少交換次數

不能列舉兩頭鹿交換,因為一頭鹿可能交換多次後轉移到下乙個狀態

那就列舉子集 dp[i]=min

初始化:將i這個狀態上的麋鹿的角從小到大排序後,若相鄰的i和i+1滿足 h[i+1]-h[i]<=c,則dp[i]=鹿的個數-1,否則dp[i]=inf

因為若有t隻鹿,在確保一定能通過交換滿足要求的情況下,直接把它需要的那個換過來即可

#include#include

#include

using

namespace

std;

int a[17],b[17

]; int dp[1

<<16

];int tmp[33

];int

main()

if(!tag)

sort(tmp+1,tmp+tot+1

);

for(int j=1;j<=tot;j+=2

)

if(tmp[j+1]-tmp[j]>m)

if(tag) dp[i]=tot/2-1

; }

for(int s=1;ss)

for(int t=(s-1)&s;t;t=(t-1)&s)

dp[s]=min(dp[s],dp[t]+dp[s^t]);

if(dp[s-1]>=n) printf("-1"

);

else printf("

%d",dp[s-1

]);}

bzoj3900 交換茸角

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

bzoj3900 交換茸角(狀壓DP)

神題一道,入手毫無思路 還是頭一次寫這種找下界的狀壓dp,首先,n頭路,我們的最大交換次數為n 1次 因為把所有鹿的茸角打亂重新分配的話,只需要n 1次就可按照從小到大的順序完成重排 這也是差值最小的方法,但是如果這樣都不合法的話,說明這個集合沒法重排,輸出 1 好了,那麼說說怎麼優化 對於每乙個集...

3900 交換茸角

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