郵票面值設計(codevs 1047) 題解

2021-07-09 09:34:38 字數 1873 閱讀 6999

【問題描述】

給定乙個信封,最多隻允許貼上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的時候,就可以不要再往下了(因為再往下就不是連續的了)。

這樣一來就好辦了,每一次找出來連續的郵票數最多的時候,就更新最優解。詳見**。

1

var 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分之間的每乙個郵資值都能得到 當然還...