储钱罐

【题目描述】

今年的ACM比赛在xxx国举行,为了比赛的顺利进行,必须提前预算好需要的费用,以及费用的来源。费用的主要来源是只进不出的金钱。其实原理很简单,每当ACM成员有任何一点小钱,他们就会把这些钱全部投进储钱罐。你知道钱投进储钱罐后是无法再取出来的,除非你打碎储钱罐,而这是不允许的。经过一段足够长时间的积累,储钱罐中应该有足够的金钱来支付ACM比赛需要的一切费用。

    储钱罐不允许打碎,我们也不能确定里面有多少钱,钱是否够用。不过,我们知道储钱罐以及每种硬币的重量,于是我们可以试着猜测里面有多少钱。为了保险起见,在已知重量的前提下,我们需要算出储钱罐中最少有多少钱(每种硬币可以使用多次,)。你能帮忙预算一下吗?

【输入】

第一行,两个正整数E和F,分别为空储钱罐的重量和装满硬币的储钱罐的重量(重量的单位是克,并且不会超过10公斤,即:1 <= E <= F <= 10000)。

第二行,有一个正整数n(1 <= N <= 500),为硬币的种类。

后面紧跟n行,每行为一种硬币类型,包含两个正整数p和w ,p为硬币的价值,w为硬币的重量,单位为克。(1 < = P < = 50000,1 < = W < = 10000)。

【输出】

输出只有一行,如果能求出符合要求的储蓄罐的最低金额,则输出该金额,否则输出“This is impossible.”。

【输入样例1】

10 110

2

1 1

30 50

【输出样例1】

60

【输入样例2】

10 110

2

1 1

50 30

【输出样例2】

100

【输入样例3】

1 6

2

10 3

20 4

【输出样例3】

This is impossible.

 

一句话题意:恰好装满容量为ff-e的背包,需要的最少硬币金额是多少?

分析:完全背包问题+恰好装满+最小值 

 f[i,j]:=min{f[i-1,j-K*w[i]]+K*p[i]}(k>=0)=min{f[i-1,j],f[i-1,j-K*w[i]]+K*p[i]}(k>=1)

 f[i-1,j-K*w[i]]+K*p[i](K>=1)

    =min{f[i-1,j], f[i-1,(j-w[i])-k*w[i]]+k*p[i]+p[i](K>=0)}

    =min{ f[i-1,j], f[i,(j-w[i])+p[i]}

初始值(在没有任何物品可以放入背包时的合法状态):

   f[0]=0;       //容量为0的背包可能被价值为0的nothing“恰好装满”

   f[1~n]=+∞  //其它容量的背包均没有合法的解,属于未定义的状态,本题又是求最小值,则初始值就应该是∞了。

 

 

 1 const
 2   maxm=20000;
 3   maxnum=30000000;
 4 var
 5   e,ff,n,m,t,i:longint;
 6   p,w:array[0..600] of longint;
 7   f:array[0..20000]of longint;
 8   procedure init;
 9   var i:longint;
10   begin
11  //   assign(input,'pig.in');reset(input);
12 
13     readln(e,ff);
14     m:=ff-e;
15     readln(n);
16     for i:=1 to n do readln(p[i],w[i]);
17    // close(input);
18   end;
19   procedure wqdp;
20   var i,j:longint;
21   begin
22     f[0]:=0;
23     for i:=1 to maxm do f[i]:=maxnum;
24     for i:=1 to n do
25       for j:=1 to m do
26         if (j>=w[i]) and(f[j]>f[j-w[i]]+p[i])  then
27           f[j]:=f[j-w[i]]+p[i];
28   end;
29   procedure print;
30   begin
31     if f[m]=maxnum then writeln('This is impossible.')
32     else writeln('The minimum amount of money in the piggy-bank is ',f[m],'.');
33   end;
34 begin
35  // readln(t);
36  // for i:=1 to t do
37  // begin
38   init;
39   wqdp;
40   print;
41  // end;
42 end.
View Code