0/1背包

 1 program package;
 2 const 
 3   maxm=200;maxn=30;
 4 var 
 5   m,n,j,i:integer;
 6   c,w: array[1..maxn] of integer;
 7   f:array[0..maxn,0..maxm] of integer;
 8 function max(x,y:integer):integer;            //求x和y的最大值
 9 begin
10   if x>y then max:=x else max:=y;
11 end;
12 
13 BEGIN 14 assign(input,'package.in'); 15 assign(output,'package.out'); 16 reset(input); 17 rewrite(output); 18 readln(m,n); //背包容量m和物品数量n 19 for i:= 1 to n do 20 readln(w[i],c[i]); //每个物品的重量和价值 21 for i:=1 to n do 22 for j:=1 to m do 23 begin // f(i,x)表示前i件物品,总重量不超过x的最优价值 24 if j>=w[i] then f[i,j]:=max(f[i-1,j-w[i]]+c[i],f[i-1,j]) 25 else f[i,j]:=f[i-1,j]; 26 end; 27 writeln(f[n,m]); //f(n,m)为最优解 28 close(input); 29 close(output); 30 END.

使用二维数组存储各子问题时方便,但当maxm较大时不能定义二维数组f,怎么办,其实可以用一维数组。

 

 1 program star_package;
 2 var
 3     i,j,k,n,m:longint;
 4     f:array[0..100000]of longint;
 5     w,c:array[0..2000]of longint;
 6 begin
 7   assign(input,'package.in');
 8   assign(output,'package.out'); 
 9   reset(input);
10   rewrite(output);
11   fillchar(f,sizeof(f),0);
12   readln(m,n);                                //背包容量m和物品数量n
13   for i:=1 to n do 
14      readln(w[i],c[i]);                        //每个物品的重量和价值
15   for i:=1 to n do
16     for j:=m downto w[i] do                    //这里不能写成for j:=w[i] to m
17       if f[j-w[i]]+c[i]>f[j] then f[j]:=f[j-w[i]]+c[i];    // f(j)表示重量不超过j公斤的最大价值
18   writeln(f[m]);
19   close(input);
20   close(ouptut);
21 end.

      为了输出方案,我们需要在每一步判断取还是不取某件物品时,需要把这个决策信息也记录下来,例如,我们可以修改f[i,j]为记录类型,分别记录数据和决策信息,f[i,j].d记录当前最大价值,f[i,j].s记录当前决策0或1,表示取还是不取该物品。当我们求出目标状态f[n,m]后,我们根据记录的信息从后往前就可以找出一种具体方案,具体实现方法见程序:

参考程序2:输出一种方案

 1 program beibao;  
 2 const
 3    maxm=200;maxn=30; 
 4 type ar=array[1..maxn] of integer; 
 5        stat=record           
 6                  d:integer;          
 7                  s:integer;
 8             end; 
 9 var 
10    m,n,j,i:integer;  
11    c,w:ar; 
12    f:array[0..maxn,0..maxm] of stat; 
13    s:array[1..maxn] of integer;  
14 function max(x,y:integer):integer; 
15 begin 
16    if x>y then begin max:=x; f[i,j].s:=1; end 
17      else begin max:=y; f[i,j].s:=0; end; 
18    end; 
19 begin 
20  assign(input,'beibao.in');  reset(input);   
21  readln(m);   
22  readln(n); 
23  for i:= 1 to n do 
24  read(w[i]); 
25  for i:= 1 to n do 
26  read(c[i]); 
27  for i:=1 to m do f[0,i].d:=0; 
28  for i:=1 to n do f[i,0].d:=0; 
29  for i:=1 to n do 
30    for j:=1 to m do
31      begin 
32          if j>=w[i]  then f[i,j].d:=max(f[i-1,j-w[i]].d+c[i],f[i-1,j].d)
33            else  begin f[i,j].d:=f[i-1,j].d; f[i,j].s:=0; end; 
34      end;
35  j:=m; 
36  for i:=n downto 1 do 
37    begin 
38      s[i]:=f[i,j].s;
39      if f[i,j].s=1 then j:=j-w[i]; 
40    end;
41    writeln; 
42   for i:=1 to n do 
43    write(s[i]);
44   writeln; 
45   writeln(f[n,m].d); 
46   close(input); 
47 end. 

经典:背包九讲

posted @ 2016-04-18 00:00  ZJQCation  阅读(236)  评论(0编辑  收藏  举报