HDU 2546 飯卡( 變形01揹包)兩種思路

2021-06-26 21:36:20 字數 2502 閱讀 2550

中文題:給你n個菜的**,問m元最少剩下多少。乙個條件是:若大於等於5元可以任意刷一次。卡上金額一定要大於5才可以

第一種:

dp[j] 用前n-1個物品能否構成j元

變形01揹包。若整個菜的價值和都小於m則m-sum;

否則,按公升序排序,易證最後用5購買的菜必然是最後乙個。先將揹包前n-1個放入,看能放入的資料是多少,然後判斷m-5後能出現哪些,利用規則替換n物品

#include#include#include#include#includeusing namespacestd;#define max(a,b) ( (a) > (b) ?(a) : (b) )

#define min(a,b) ( (a) < (b) ?(a) : (b) )

#define maxn 1100

inta[maxn];

intdp[maxn];

intmain

()sort(a+1,a+1+n);memset(dp,0,

sizeof

(dp));dp[0]=1;

intans=0;

for(i=1;i<n;i++)

for(j=m+50;j>=a[i];j--)

if(dp[j-a[i]])dp[j]=1,ans=max(ans,j);

if(ans+a[n]<=m)printf("%d\n",m-a[n]-ans);

else

elseans=min(ans,i);

}printf("%d\n",ans);}}

return0;

}

第二種:用m-5充分裝菜,最後再用5裝n,就可以了

dp[j] 前n-1個物品,用j元最多買多少錢的菜。

#define max(a,b) ( (a) > (b) ?(a) : (b) )

#define min(a,b) ( (a) < (b) ?(a) : (b) )

#include#include#include#includeusing namespace std;

int main()

,price[2014]=;

while(scanf("%d",&n)!=eof,n)

cin>>m;

if(m<5)

sort(price+1,price+n+1);

maxn=price[n];

m=m-5;

for(i=1;i=price[i];j--)

}printf("%d\n",m+5-dp[m]-maxn);

}return 0;}/*

150510

1 2 3 2 1 1 2 3 2 1506

10 30 45 50 25 15

1116

10 30 45 50 25 15

4*/

HDU 2546 飯卡 01揹包變形

分析 每種菜可買一次或者不買,所以是01揹包 餘額m 5,只能買 餘額的菜 無法購買 餘額m 5,買最貴的菜 餘額m 5,先用 h m 5 去買菜,再用5去買最貴的菜。h視為揹包容量,菜的 a i 視為重量w和價值c。ac include include includeusing namespace...

HDU2546 飯卡 01揹包

problem description 電子科大本部食堂的飯卡有一種很詭異的設計,即在購買之前判斷餘額。如果購買乙個商品之前,卡上的剩餘金額大於或等於5元,就一定可以購買成功 即使購買後卡上餘額為負 否則無法購買 即使金額足夠 所以大家都希望盡量使卡上的餘額最少。某天,食堂中有n種菜 每種菜可購買一...

HDU 2546 飯卡 01揹包

我的做法是找出n種菜中最貴的 k,把揹包的容量m增加的到m k 然後對 排個序,因為dp是從第乙個菜到最後乙個菜,越貴的菜越後選結果越小,然後進行dp include include include include using namespace std const int maxn 1010 in...