Hrbust 1333 GG的關心 01揹包

2022-09-17 13:48:14 字數 1855 閱讀 9035

電腦買回來後,mm一直用它專心的搞acm,看著mm專注的樣子,gg也是非常開心,但害怕mm勞累過度影響身體,於是gg經常到超市給mm買一些營養品來補充身體能量。gg到超市購物從來都是刷卡的,可是這種卡很詭異,當用它在超市購物的時候,刷卡機會先判斷卡上的餘額是否低於5元錢。如果低於5元錢則無法購買任何物品,即使那件物品的金額是小於5的也不可以。而如果卡上的金額大於等於5元則可以進行交易,即使交易成功後卡中餘額為負數也是可以的。

現在超市有n種物品,每種物品最多只能買乙個。已知每種物品的**和卡上的餘額。問最少可使卡上的餘額為多少。

input

輸入包含多組資料。對於每一組資料:

第一行有兩個正整數n和m,分別代表物品的種類數,以及卡中的餘額。

第二行包含n個正整數p1,p2,p3…pn,分別代表每一種物品的**。

當n為0時表示輸入結束

範圍:m, n <= 1000

pi <= 50 (1 <= i <= n)

output

對於每組輸入,輸出乙個整數並換行,代表卡上可能的最小餘額。

sample input

1 550

10 50

1 2 3 2 1 1 2 3 2 1

0sample output

-4532

hint

買東西是一件一件買。

題解:對於這題可以這麼想,他要求餘額最少,並且當餘額大於等於5元時仍可以買一件任意**的物品。於是很容易想到,一定要留個5元來買最貴的物品。

那麼真正的可以金額就是 初始金額-5 。

真正可用金額花的越多,剩下的越少,在買完最貴的物品之後,剩餘的錢就越少,就是最優解。於是轉換成了乙個01揹包問題

在容量為 初始金額-m 的揹包裡盡可能裝入價值較高的物品。

最後的結果=【總金額-最大價值物品-揹包可裝入的最大價值】

在揹包部分其實已經很裸了,對於一件商品【排序後】,我們選擇不買這件商品或買這件商品。

即max(dp[j],dp[j-a[i]]+a[i])

dp[j]表示擁有金額j時最多可以花掉多少錢

#include

///01揹包的變形

#include

#include

using namespace std;

intmain()

scanf

("%d"

,&m)

;for

(i=0

;i)///輸入部分

if(m<5)

///因為輸入值m是小於1000的,因此當輸入的本金少於5時什麼都買不了,就直接輸出原有金額就好

sort

(a,a+n)

;///排序,按從小到大的順序乙個個購買,這樣才能從基礎部分一遍遍更新dp陣列,因為在計算更大價錢的物品時,會需要買便宜物品的時記錄的資料

memset

(dp,0,

sizeof

(dp));

///記得清空陣列

for(i=

0;i1;i++

)///揹包部分,從第1個物品到第n-1個物品,因為最後乙個物品是最大值,之後會單獨計算,因此不能在揹包中被統入

// for(int k=m-5;k>=0;k--)///這裡可以看出每次遍歷,動態規劃陣列的更新路徑

//

// printf("*****=\n");

}///取出最貴的物品,留在揹包完成後減去,是餘額最少的

printf

("%d\n"

,m-dp[m-5]

-a[n-1]

);}return0;

}

山東理工ACM 1333

請使用字串比較函式,比較兩個字串的大小,並按要求輸出比較後的結果。字串最長不超過15個字元。輸入兩個字串str1和str2,如果第乙個字串與第二個字串相等,輸出str1 str2,如果第乙個字串大於第二個字串,輸出str1 str2,如果第乙個字串小於第二個字串,輸出str1 str2。第1行為第乙...

sjtu1333 函式時代

taring說 生活的過程就是執行函式的過程。需要命令,也需要回報。更重要的,是得到回報的過程。好吧。這道題其實和上面的也沒啥關係tat,我們要求的是下面的問題 給定 n 個數,第 i 個數為 a i 再給定乙個常數h。現在,你要把這 n 個數,分成兩個集合,且這兩個集合的並集為這 n 個數的全集 ...

Hrbust 合唱隊形

description 一年一度的清明節又要到了 學校決定開個晚會慶祝一下 由於泥工男孩子實在太多啦,跳舞是不可能跳舞的。於是他們決定站成一排唱歌。眾所周知的,老師往往都是有強迫症的人。他想要讓最終隊形的身高序列從左到右先嚴格不減再嚴格不增。比如 1,2,3,2,1 1,4,4,2 1,2,3 都是...