郵票面值設計

2022-04-02 18:07:40 字數 3629 閱讀 1946

stamps 郵票問題

題目描述:

已知乙個 n 枚郵票的面值集合(如,)和乙個上限 k —— 表示信封上能夠貼 k 張郵票。計算從 1 到 m 的最大連續可貼出的郵資。 

例如,假設有 1 分和 3 分的郵票;你最多可以貼 5 張郵票。很容易貼出 1 到 5 分的郵資(用 1 分郵票貼就行了),接下來的郵資也不難: 

6 = 3 + 3 

7 = 3 + 3 + 1 

8 = 3 + 3 + 1 + 1 

9 = 3 + 3 + 3 

10 = 3 + 3 + 3 + 1 

11 = 3 + 3 + 3 + 1 + 1 

12 = 3 + 3 + 3 + 3 

13 = 3 + 3 + 3 + 3 + 1

然而,使用 5 枚 1 分或者 3 分的郵票根本不可能貼出 14 分的郵資。因此,對於這兩種郵票的集合和上限 k=5,答案是 m=13。

輸入:第 1 行: 兩個整數,k 和 n。k(1 <= k <= 200)是可用的郵票總數。n(1 <= n <= 50)是郵票面值的數量。 

第 2 行至末尾: n 個整數,每行 15 個,列出所有的 n 個郵票的面值,面值不超過 10000。

輸出:

乙個整數,從 1 分開始連續的可用集合中不多於 k 張郵票貼出的郵資數。

樣例輸入:

5 21 3

樣例輸出:

分析:

1.資料分析:每個信封最多貼k(k<=200)張郵票,每張郵票的面值不超過10000,能貼出最大的郵資不超過2000000,可用乙個陣列來表示能夠表示貼出每種郵資。

2.演算法分析:

(1)搜尋:每種郵票最多貼200張,總共50種,樸素的深搜規模將達到50^200。

(2)動態規劃:

<1>階段:能夠構成每個面值為階段。比如能構成的面值為1到v,那麼總共為v個階段。

<2>狀態:dp[i]表示構成面值i所需要的最少郵票數.

<3>決策:對於樣例資料1和3兩種面值的郵票:

構成郵資0:所需要郵票張數為0張,dp[0]=0;

構成郵資1:只能用1分的郵票,所需要郵票張數1張,dp[1]=1;

構成郵資2:只能用1分的郵票,所需要郵票張數2張,dp[2]=1;

構成郵資3:

*1.若選擇使用一張1分的郵票,dp[3]=dp[2]+1=3………dp[3-1]+1

*2.若選擇使用一張3分的郵票,dp[3]=dp[0]+1=1………dp[3-3]+1

dp[3]=min=1;

構成郵資4:

*1.若選擇使用一張1分的郵票,dp[4]=dp[3]+1=2………dp[3-1]+1

*2.若選擇使用一張3分的郵票,dp[4]=dp[1]+1=1………dp[3-3]+1

dp[4]=min=2;

<4>狀態轉移方程:dp[i]=min    i>=a[j]  1<=j<=n    f[i]<=k;

樣例**:

#include #include 

using

namespace

std;

int dp[2000001

];int

main()

printf(

"%d\n

",i-1

); }

return0;

}

實質就是揹包問題:當前郵資i可以看作揹包容量,每種郵票可以看作是乙個物品,郵票的面值就是物品的體積,k可以看作是對物品數量的乙個限制。stamps 郵票面值設計問題題目描述:

給定乙個信封,最多隻允許貼上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 2樣例輸出:

1 3max=7

這道題顯然要先搜尋出滿足條件的面值組合,比如n=3,k=3時

在搜尋時加入適當優化:

以n=3,k=3為例:第乙個面值肯定為1,但是第二個面值只能是2,3,4,因為面值為1的最多貼3張,貼滿的最大值為3,要保證數字連續,那麼第二個數字最大只能是4。所以我們可以得到規律,如果郵票張數為n,種類為k,那麼從小到大的順序,郵票a[i]的下一種面值的取值範圍必然是a[i]+1到a[i]*n+1如圖:

演算法:深度優先搜尋+動態規劃

如果已知郵票的不同面值,可以用動態規劃求出這些不同面值的郵票能組合出的最大連續數:

設dp[i]表示已知面值的郵票組合出面值為i所需要的最小郵票數,我們把已知的q種不同的郵票面值存在num中,則有狀態轉移方程:

dp[i]=min

最後隨著深度搜尋不斷列舉可能的面值組合,然後不斷更新最大值即可

**:

#include int dp[4000001],a[40]=,max_a[40

];int

max,n,k;

void youpiao() //

驗證當前郵票組合的最大連續數

if(i-1>max) //

一旦當前最大數大於了max,就更新max,並把當前的組合方式存在max_a陣列中.

}void dfs(int step) //

列舉所有可能的郵票種類組合

inti;

for(i=a[step-1]+1;i<=a[step-1]*n+1;i++)

} intmain()

printf(

"\nmax=%d\n

",max);

}return0;

}

原文

郵票面值設計

演算法提高 郵票面值設計 時間限制 1.0s 記憶體限制 256.0mb 提交此題 錦囊1 錦囊2 問題描述 給定乙個信封,最多隻允許貼上n張郵票,計算在給定k n k 13 種郵票的情況下 假定所有的郵票數量都足夠 如何設計郵票的面值,能得到最大值max,使在1 max之間的每乙個郵資值都能得到。...

郵票面值設計

題目描述 給定乙個信封,最多隻允許貼上nn張郵票,計算在給定kk n k 15 種郵票的情況下 假定所有的郵票數量都足夠 如何設計郵票的面值,能得到最大值max,使在1至max之間的每乙個郵資值都能得到。例如,n 3,k 2,如果面值分別為1分 4分,則在1分 6分之間的每乙個郵資值都能得到 當然還...

wikioi 1047 郵票面值設計

同樣感觸很深的一道題,之前打表,後來自己寫了一遍 具體就是用深搜找方案,用dp判斷 一道很經典的dfs套dp,但是程式很多地方還需優化 void dfs int num,int tk,int m 當前數值,種數,估計能構成的最大值 maxn cnt return for int i check m,...