【洛谷】P2725 郵票 Stamps(dp)
阿新 • • 發佈:2017-10-28
adg symbol 能夠 循環 tro 總數 技術分享 std 答案
題目背景
給一組 N 枚郵票的面值集合(如,{1 分,3 分})和一個上限 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。 [規模最大的一個點的時限是3s]
小提示:因為14貼不出來,所以最高上限是13而不是15
輸入輸出格式
輸入格式:
第 1 行: 兩個整數,K 和 N。K(1 <= K <= 200)是可用的郵票總數。N(1 <= N <= 50)是郵票面值的數量。
第 2 行 .. 文件末: N 個整數,每行 15 個,列出所有的 N 個郵票的面值,每張郵票的面值不超過 10000。
輸出格式:
第 1 行:一個整數,從 1 分開始連續的可用集合中不多於 K 張郵票貼出的郵資數。
輸入輸出樣例
輸入樣例#1: 復制5 2 1 3輸出樣例#1: 復制
13
說明
題目翻譯來自NOCOW。
USACO Training Section 3.1
---------------------------------------------------------------------------------------------------
分析:用dp[i]表示最少用幾張牌組成i方程,需要一個小技巧:我們可以將k這個條件轉化成求什麽時候,需要組成數字i的牌數>k。
剩下的話,不難想到,,用這個式子跑循環就可以了。
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 const int maxn=2000005; 5 int dp[maxn],a[100];//dp[i]:用幾張牌組成i 6 int main() 7 { 8 int n,k; 9 scanf("%d%d",&k,&n); 10 for(int i=1;i<=n;i++) 11 { 12 scanf("%d",&a[i]); 13 } 14 for(int i=0;i<maxn;i++) dp[i]=999999999; 15 dp[0]=0; 16 for(int i=1;i<=n;i++) 17 { 18 for(int j=a[i];j<=maxn;j++) 19 { 20 dp[j]=min(dp[j],dp[j-a[i]]+1); 21 } 22 } 23 for(int i=1;i<=maxn;i++) 24 { 25 if(dp[i]>k||dp[i]<1) 26 { 27 printf("%d\n",i-1); 28 return 0; 29 } 30 } 31 return 0; 32 }
【洛谷】P2725 郵票 Stamps(dp)