1999NOIp提高組 郵票面值設計

2021-09-01 02:51:47 字數 1384 閱讀 4833

給定乙個信封,最多隻允許貼上n張郵票,計算在給定k(n+k≤15)種郵票的情況下(假定所有的郵票數量都足夠),如何設計郵票的面值,能得到最大值max,使在11至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分。

輸入格式:

2個整數,代表n,k。

輸出格式:

2行。第一行若干個數字,表示選擇的面值,從小到大排序。

第二行,輸出「max=s」,s表示最大的面值。

輸入3 2

輸出

1 3

max=7

這一道題不難想出用搜尋做,通過列舉列舉出所有種類的郵票,最後判斷一下,並記錄最大值

但是,直接暴力搜尋肯定會超時的,所以我用了以下幾個剪枝優化:

(在這裡我用a陣列記錄搜尋的值)

剪枝1:我們可以使a陣列保持單調遞增,dfs中每次從a[k-1]+1開始搜尋,以此來消除重複的搜尋

剪枝2:我們通過看題,可以知道1肯定會被選用,不然怎麼組成1的,所以我們使a[1]=1,然後從第2項開始搜尋(這個剪枝意義不大,不過個人喜歡)

剪枝3:這個剪枝可以說是這一道題的難點,

(每次從a[k-1]+1到50是肯定會超時的)

假設當前準備填第k個(已經填好了k-1)個

所以在前k-1個中可以湊出1-t中的所有整數(需要用dp求出t)

因此我們可以把上界定為t+1

如果超過了t+1,那麼就無法組成t+1了。

所以dfs搜尋的範圍是

for(int i=a[k-1]+1;i<=t+1;i++)
對了,剛才不是說要用dp嗎,那麼怎麼dp?

所以dp[i]=min(dp[i],dp[i-a[i]]+1),初始化+oo,dp[0]=0

**(你們最想要的):

#include#include#include#includeusing namespace std;

int n,m;

int a[21];//暫時的儲存

int maxx=0,ans[21];//ans和maxx記錄最終結果

int dp[51000];//dp陣列

int solve(int k)

return;

} int end=solve(k-1);

for(int j=a[k-1]+1;j<=end+1;j++)

}int main()

NOIP1999郵票面值設計

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

NOIP1999 郵票面值設計

時間限制 1 sec 記憶體限制 64 mb 提交 131 解決 63 提交 狀態 我的提交 給定乙個信封,最多隻允許貼上n張郵票,計算在給定k n k 40 種郵票的情況下 假定所有的郵票數量都足夠 如何設計郵票的面值,能得到最大值max,使在1 max之間的每乙個郵資值都能得到。第1行 2個整數...

郵票面值設計(NOIP1999)

傳送門 怎麼講呢?挺有意思的 是一道dp和搜尋的結合。我們把數字從小到大依次列舉。用dp去計算當前的所得最大值。f i 表示湊成i面值所需的最小郵票數量。那麼小於等於n的,都是可以湊出來的。那麼最大值也就好求了。至於dp的上界,用幾個數的和就能解決。如下 include include includ...