計蒜客習題 蒜頭君的積木

2022-07-16 19:57:16 字數 1249 閱讀 8554

問題描述

蒜頭君酷愛搭積木,他用積木搭了 n 輛重量為 wi的小車和一艘最大載重量為 w 的小船,他想用這艘小船將 n 輛小車運輸過河。每次小船運載的小車重量不能超過 w。另外,小船在運載小車時,每輛小車會對小船有乙個損壞值si,當多輛小車一起運載時,該趟運載對小船的損壞值為船上所有小車的最大損壞值。

現在蒜頭君想知道,如何用小船運載 n 輛小車,可以使得對小船造成的總損壞值最小。

輸入格式

第一行輸入兩個數 w 和 n(100≤w≤400,1≤n≤16),分別表示小船的最大載重量和小車總數。

接下來輸入 n 行,每行輸入兩個整數si和 wi(1≤si ≤50,10≤wi≤100),分別表示每輛小車對小船的損壞值和每輛小車的重量。

輸出格式 

輸出一行,輸出乙個整數,表示用小船運載 nn 輛小車,最小的總損壞值。

樣例輸入

90 4

32 50

15 20

40 50

13 40

樣例輸出

72狀壓dp裡的經典做法,列舉子集。

for(int j=0;j

for(int k=j;k;k=(k-1)&j)

仔細揣摩一下上面的**,這樣列舉子集的效率是很高的。請記住!

對於這道題很容易想到,對於要求解的任意乙個方案(第i輛搬不搬),可以通過其子集求解,我們列舉其子集代表達成此方案的最後一次運載,取補集就是之前完成的,這樣dp[j]=min。為了提高效率我們可以先預處理出每種情況的花費。

1 #include2 #include3 inline int min(int a,int b) 

4 inline int max(int a,int b)

5const

int maxw=405,maxn=20,inf=0x3f3f3f3f;6

int w,n,s[maxn],w[maxn],dp[1

<1

<1

<

7int get_w(int

i) 13

return

ans_w;14}

15int get_c(int

i) 21

return

ans_c;22}

23int

main() 34}

35 printf("

%d",dp[(1

<1

]);36

return0;

37 }

ac**

計蒜客習題 蒜頭君倒水

推出轉移矩陣 1 xyx1 y begin 1 x y x 1 y end 1 xx y1 y 之後的就很顯然了 倒了幾次就是求轉移矩陣的幾次冪 然後乘上原矩陣 ab begin a b end ab 即可 傳送門注意矩陣乘法不滿足交換律 includeusing namespace std dou...

計蒜客習題 蒜頭君走迷宮

蒜頭君從乙個 n 行 m 列的迷宮的左上角走到右下角,蒜頭君每次只能向下或者向右走一步,蒜頭君想知道他有多少種走法。輸入格式 輸入兩個整數 n 2 n 10 5 m 2 m 10 5 輸出格式 由於方案數太多,輸出最後結果對 1000000007 取模的結果。樣例輸入 2 3 樣例輸出 3 incl...

計蒜客習題 蒜頭君的訓練室

蒜頭君的訓練室有 n 個站點,另外有 m 條單向邊連線這些站點。第 i 條路從 si站到 ei站,有高度為 hi的圍欄,蒜頭君是需要跳躍的。現在蒜頭君們有 t 個任務要完成。第 ii 個任務,蒜頭君要從 ai站到 bi站,蒜頭君想要他們路徑中最高圍欄盡可能小。請你確定這個高度。輸入格式 第一行輸入三...