首页 > 代码库 > 回溯法第2题—邮票问题

回溯法第2题—邮票问题

[问题描述]

设有已知面额的邮票m种,每种有n张。问:用总数不超过n张的邮票进行组合,能组合的邮票面额中可以连续出现的面额数最多有多少?

(1<=m<=100,1<=n<=100,1<=邮票面额<=225)

输入:第一行:n和m的值,中间用一空格隔开。

        第二行:a[1..m](面额),每个数中间用一空格隔开。
输出:连续面额数的最大值

[样例输入]

4 31 2 4

[样例输出]

14

[问题分析]

我写的程序

var a:array[0..100]of integer;    money,f:array[0..255]of integer;    n,m:integer;    maxlong:integer;procedure qsort(l,r:integer);//偷懒直接从FPC文件夹里copy来的var i,j,x,y:integer;begin  i:=l;j:=r;x:=a[(l+r) >> 1];  repeat    while a[i]<x do inc(i);    while x<a[j] do dec(j);    if not(i>j) then       begin         y:=a[i];a[i]:=a[j];a[j]:=y;         inc(i);dec(j);       end;  until i>j;  if l<j then qsort(l,j);  if i<r then qsort(i,r);end;procedure init;var i:integer;begin  readln(n,m);  for i:=1 to m do read(a[i]);  qsort(1,m);end;procedure search(k,n,x:integer);//k:第k个已知面额,n:可用已知面额的最多数量,x:目前已构成的面额值var i:integer;begin  if (n=0)or(k=0) then exit;  for i:=n downto 0 do    begin      inc(x,a[k]*i);      dec(n,i);      inc(money[x]);      search(k-1,n,x);      inc(n,i);      dec(x,a[k]*i);    end;end;procedure count;var i,max:integer;begin  f[0]:=0;  max:=0;  for i:=1 to 255 do    if  money[i]>0 then      begin        f[i]:=f[i-1]+1;        if f[i]>max then max:=f[i];      end     else f[i]:=0;  writeln(max);end;begin  init;  search(m,n,0);  count; end.

标准程序:

var  a:array  [1..100]  of  integer;  money:array  [1..2550]  of  integer;  total,n,m,i:integer;procedure  search(k,n,x:integer);var  i:integer;begin  if  (n=0)or(k=0)  then  exit;  for  i:=n  downto 0  do        begin           x:=x+a[k]*i;           n:=n-i;           money[x]:=money[x]+1;           search(k-1,n,x);           x:=x-a[k]*i;           n:=n+i;       endend;function maxlong:integer;var  j,total,max:integer;begin j:=n*a[m]; max:=0; repeat   while  (money[j]=0)and(j>0)  do      j:=j-1;   total:=0;   while  (money[j]>0)and(j>0)  do     begin total:=total+1;j:=j-1 end;   if  max<total then  max:=total   ; until  j<=0; maxlong:=maxend;begin  assign(input,word.in);  reset(input);  assign(output,word.out);  rewrite(output);  readln(m,n);  for  i:=1  to  m  do  read(a[i]);  total:=0;  search(m,n,0);  writeln(maxlong)end.

真心感觉这一次的标准程序给的很好,这道题也有动态规划的做法,由于我现在在学习回溯法,就暂时不介绍DP方法了。