狀壓動規 BSOJ3805 小貓爬山

2021-07-22 09:58:54 字數 1673 閱讀 2004

3805 -- 【模擬試題】小貓爬山

description

freda和rainbow飼養了n只小貓,這天,小貓們要去爬山。經歷了千辛萬苦,小貓們終於爬上了山頂,但是疲倦的它們再也不想徒步走下山了(嗚咕》_<) 。

freda和rainbow只好花錢讓它們坐索道下山。索道上的纜車最大承重量為w,而n只小貓的重量分別是c1、c2……cn。當然,每輛纜車上的小貓的重量之和不能超過w。每租用一輛纜車,freda和rainbow就要付1美元,所以他們想知道,最少需要付多少美元才能把這n只小貓都運送下山?

input

第一行包含兩個用空格隔開的整數,n和w。

接下來 n 行每行乙個整數,其中第i+1行的整數表示第i只小貓的重量ci。

output

輸出乙個整數,最少需要多少美元,也就是最少需要多少輛纜車。

sample input

5 1996 1

21994 12

29

sample output2

hint

【資料範圍】對於100%的資料,1<=n<=18,1<=ci<=w<=10^8。

看到奇特的n範圍就要往這邊想了,當然,這種資料範圍也有可能是迭代深搜、分層圖、拆點等等,這次的狀壓dp(標程是迭代深搜)。

我們往狀壓這一方面想,設f[state]為state狀態下最少用車,那麼怎麼判斷當前車放得下某只貓呢?

解決方案是簡單的,記錄rest[state],表示state狀態下當前車可用重量,dp的時候判斷一下既可以了。

這樣dp就好了嘛?

哦豁,40分。

事實是這樣的:

對於乙個「集合」abc,假設有這麼幾種方法來構造:

1:a+bc

2:b+ac

3:c+ab

這樣問題就來了,現在已經有了乙個abc,對於乙個新的構造方法,必須要比較一次,才能得到更優解,不能因為這個集合已經有解,就忽略這個新的解。

在這道dp裡面,這個思想體現在這個細節裡面:

我什麼時候更新f[state]?

40分的程式,僅僅當有更優的f[state]的時候,才去更新;

100分的程式,僅需加乙個地方:有同樣的f,但是新的解的rest[state]比原來的更大時,這個解就是更優解。

這個思想就體現在這裡。

剩下的就是樸素狀壓了!

太可惜了,考試的時候就差這幾句話。

貼上**:

#include#include#include#include#includeusing namespace std;

int f[262150]=,rest[262150]=,n,w,weight[100005]=,ed;

void init()

else

if(tempfrest[newstate]))}}

printf("%d\n",f[ed-1]);

}int main()

複習動規(3)

繼續複習動規。第一道,scoi2010 交易。看起來限制多,其實就是紙老虎。可設f i j 指第i天擁有j張 所賺的最大錢數,所以f i j 可為負,所以初值設為 inf。四種情況 1.什麼都不買,f i j max 2.第一次買,f i j max 0 j asi 3.之後的買,f i j max...

USACO 狀壓DP練習 3

1725 題意 m n m,n le 12 的牧場,有的格仔不能選,相鄰不能同時選,求方案數 f i j 前 i 行當前行選的集合為 j include include include include include using namespace std typedef long long ll ...

每日演算法 動規高頻題 3

1 target 目標位置 10000 啊那個r僅僅是轉向還有剎車的意思,並不一樣要後開乙個位置,俺就是看著結果莫名其妙的。能夠直接到達的位置是2n 1這種型別的位置,如果無法到達就有兩種清空。1.開過了,得倒回來,這種情況比較簡單,只需加上開到過了的那個位置的運算元 n 開回來的次數 2n 1 x...