洛谷P2725 郵票 Stamps
題目背景
給一組 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
_________________________________________________________________________________________________________________________________________________________________________________________________________________
一個完全背包的題,f[i] 表示當面值為 i 時最少需要的郵票數
狀態轉移方程:f[j]=min(f[j],f[j-a[i]]+1)(其中 a[i] 表示第 i 個郵票的面值)
1 #include<iostream> 2 using namespace std; 3 int n,k,s,f[2000001],a[51]; 4 int main() 5 { 6 cin>>k>>n; 7 for(int i=1;i<=2000000;i++) 8 f[i]=12345678; 9 for(int i=1;i<=n;i++) 10 cin>>a[i]; 11 for(int i=1;i<=n;i++) 12 for(int j=a[i];j<=2000000;j++) 13 if(f[j-a[i]]+1<=k) 14 f[j]=min(f[j],f[j-a[i]]+1); 15 for(int i=1;i<=2000000;i++) 16 if(f[i]==12345678) 17 { 18 s=i-1; 19 break; 20 } 21 cout<<s; 22 return 0; 23 }代碼
洛谷P2725 郵票 Stamps