主题:谁帮我解释一下 邮票问题????????/
设有已知面额的邮票m种,每种有n张.问:用总数不超过n张的邮票进行组合,能组合的邮票面额中可以连续出现面额数最多有多少?
例:输入 n:4 m: 3
每种面额1 2 4
输出 14
程序:program stamp;
const
max_num = 40;
max_total = 50000000;
type
arrtype= array[1..max_num] of integer;
var
n,k,max_max:integer;
value,max_value: arrtype;
num: array[0..max_total] of integer;
count:integer;
last_count:integer;
function get_max(n,k:integer; var value: arrtype): integer;
var
i,j,min_num: integer;
begin
num[0] := 0;
for i := 1 to max_total do
begin
min_num := maxint;
for j := 1 to k do
if ((i-value[j] >= 0) and (num[i-value[j]]+1 < min_num))
then
min_num := num[i-value[j]]+1;
if (min_num > n)
then
begin result := i - 1; exit end;
num[i] := min_num;
end;
result := max_total;
end;
function try_it(index,prev2_max,prev_max: integer): boolean;
var
i,cur_max: integer;
begin
result := false;
if (index = k + 1)
then
begin
inc(count);
if (prev_max > max_max)
then
begin
max_max := prev_max;
max_value := value;
last_count := count;
end;
exit;
end;
for i := prev_max + 1 downto value[index-1] + 1
do
begin
if ((index = k) and (i*n <= max_max))
then
break;
value[index] := i;
cur_max := get_max(n,index,value);
if (try_it(index+1,prev_max,cur_max))
then
begin result := true; exit; end;
end;
end;
var
i: integer;
program p1_2(input,output);
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);
total:=0;
search(m,n,0);
writeln(maxlong)
end.
[em18][em18][em18][em18][em18][em18][em18][em18][em18][em18]
例:输入 n:4 m: 3
每种面额1 2 4
输出 14
程序:program stamp;
const
max_num = 40;
max_total = 50000000;
type
arrtype= array[1..max_num] of integer;
var
n,k,max_max:integer;
value,max_value: arrtype;
num: array[0..max_total] of integer;
count:integer;
last_count:integer;
function get_max(n,k:integer; var value: arrtype): integer;
var
i,j,min_num: integer;
begin
num[0] := 0;
for i := 1 to max_total do
begin
min_num := maxint;
for j := 1 to k do
if ((i-value[j] >= 0) and (num[i-value[j]]+1 < min_num))
then
min_num := num[i-value[j]]+1;
if (min_num > n)
then
begin result := i - 1; exit end;
num[i] := min_num;
end;
result := max_total;
end;
function try_it(index,prev2_max,prev_max: integer): boolean;
var
i,cur_max: integer;
begin
result := false;
if (index = k + 1)
then
begin
inc(count);
if (prev_max > max_max)
then
begin
max_max := prev_max;
max_value := value;
last_count := count;
end;
exit;
end;
for i := prev_max + 1 downto value[index-1] + 1
do
begin
if ((index = k) and (i*n <= max_max))
then
break;
value[index] := i;
cur_max := get_max(n,index,value);
if (try_it(index+1,prev_max,cur_max))
then
begin result := true; exit; end;
end;
end;
var
i: integer;
program p1_2(input,output);
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);
total:=0;
search(m,n,0);
writeln(maxlong)
end.
[em18][em18][em18][em18][em18][em18][em18][em18][em18][em18]