码迷,mamicode.com
首页 > 其他好文 > 详细

回溯法第2题—邮票问题

时间:2014-08-12 21:40:44      阅读:400      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   文件   for   ar   问题   

[问题描述]

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

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

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

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

[样例输入]

4 3
1 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;
       end
end;
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:=max
end;
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方法了。

回溯法第2题—邮票问题,布布扣,bubuko.com

回溯法第2题—邮票问题

标签:style   blog   color   io   文件   for   ar   问题   

原文地址:http://www.cnblogs.com/cuichen/p/3908292.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!