電腦買回來後,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 都是...