[问题描述]
设有已知面额的邮票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方法了。
时间: 2024-10-14 22:16:49