【問題描述】
給定乙個信封,最多隻允許貼上n張郵票,計算在給定k(n+k≤40)種郵票的情況下(假定所有的郵票數量都足夠),如何設計郵票的面值,能得到最大值max,使在1~max之間的每乙個郵資值都能得到。例如,n=3,k=2,如果面值分別為1分、4分,則在1分~6分之間的每乙個郵資值都能得到(當然還有8分、9分和12分);如果面值分別為1分、3分,則在1分~7分之間的每乙個郵資值都能得到。可以驗證當n=3,k=2時,7分就是可以得到的連續的郵資最大值,所以max=7,面值分別為1分、3分。
3 21 3
max=7
本題為noip1999第三題,初看感覺挺簡單的(不就乙個搜尋嗎,乙個乙個往上搜就行了啊),但寫著寫著,就發現出了點問題……
下面說一說正解。
首先,我們設定乙個陣列,用來存放對於某乙個值x它所需要的最少郵票數是多少,當某個值所需要的郵票數大於k的時候,就可以不要再往下了(因為再往下就不是連續的了)。
這樣一來就好辦了,每一次找出來連續的郵票數最多的時候,就更新最優解。詳見**。
1var a,b,f:array[-1..40] of longint;//f記錄用x種郵票所取得的連續的郵票面值的最大值是多少,b是目前來說的最優解,a是最終結果
2 v:array[0..10000] of longint;//記錄x至少需要多少張郵票
3i,j,n,k:longint;
4procedure dfs(x,y:longint);//y是當前能取的最大值,x是當前取第幾張
5var
i,j,z,m:longint;
6 ss:array[0..10000] of longint;//方便回溯
7begin
8if y1] then
9 exit;//如果y比在沒有這次搜尋前的最大值還小,就不需要搜尋,肯定不是最優解
10if x>k then
11 exit;//已取完k張
12 ss:=v;
13for i:=b[x-1]+1
to y+1
do14
begin
15 b[x]:=i;//第x張取i
16 m:=y;
17 j:=0;18
while v[j]<=n do
19begin
20for z:=1
to x do
21if v[j+b[z]]>v[j]+1
then
22 v[j+b[z]]:=v[j]+1;//更新面額所需的最少郵票數
23inc(j);
24end;25
while v[m+1]<=n do
26 inc(m);//連續能取到的郵票的最大面值
27if (m>f[x])and(x=k) then//如果全部取完了,更新最優值
28 a:=b;
29if m>f[x] then//更新取x種郵票的最優值
30 f[x]:=m;
31 dfs(x+1
,m);
32 v:=ss;
33end;34
end;
35begin
36readln(n,k);
37for i:=1
to10000
do38 v[i]:=maxlongint;//初始化
39 dfs(1,0
);40
for i:=1
to k do
41 write(a[i],'');
42writeln;
43 writeln('
max=
',f[k]);
44end.
郵票面值設計
演算法提高 郵票面值設計 時間限制 1.0s 記憶體限制 256.0mb 提交此題 錦囊1 錦囊2 問題描述 給定乙個信封,最多隻允許貼上n張郵票,計算在給定k n k 13 種郵票的情況下 假定所有的郵票數量都足夠 如何設計郵票的面值,能得到最大值max,使在1 max之間的每乙個郵資值都能得到。...
郵票面值設計
stamps 郵票問題 題目描述 已知乙個 n 枚郵票的面值集合 如,和乙個上限 k 表示信封上能夠貼 k 張郵票。計算從 1 到 m 的最大連續可貼出的郵資。例如,假設有 1 分和 3 分的郵票 你最多可以貼 5 張郵票。很容易貼出 1 到 5 分的郵資 用 1 分郵票貼就行了 接下來的郵資也不難...
郵票面值設計
題目描述 給定乙個信封,最多隻允許貼上nn張郵票,計算在給定kk n k 15 種郵票的情況下 假定所有的郵票數量都足夠 如何設計郵票的面值,能得到最大值max,使在1至max之間的每乙個郵資值都能得到。例如,n 3,k 2,如果面值分別為1分 4分,則在1分 6分之間的每乙個郵資值都能得到 當然還...