Given a set of N stamp values (e.g., {1 cent, 3 cents}) and an upper limit K to the number of stamps that can fit on an envelope, calculate the largest unbroken list of postages from 1 cent to M cents that can be created.
For example, consider stamps whose values are limited to 1 cent and 3 cents; you can use at most 5 stamps. It's easy to see how to assemble postage of 1 through 5 cents (just use that many 1 cent stamps), and successive values aren't much harder:
- 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.
However, there is no way to make 14 cents of postage with 5 or fewer stamps of value 1 and 3 cents. Thus, for this set of two stamp values and a limit of K=5, the answer is M=13.
The most difficult test case for this problem has a time limit of 3 seconds.
PROGRAM NAME: stamps
INPUT FORMAT
Line 1: | Two integers K and N. K (1 <= K <= 200) is the total number of stamps that can be used. N (1 <= N <= 50) is the number of stamp values. |
Lines 2..end: | N integers, 15 per line, listing all of the N stamp values, each of which will be at most 10000. |
SAMPLE INPUT (file stamps.in)
5 2 1 3
OUTPUT FORMAT
Line 1: | One integer, the number of contiguous postage values starting at 1 cent that can be formed using no more than K stamps from the set. |
SAMPLE OUTPUT (file stamps.out)
13
思路:尝试过很多方法,虽然知道是DP,发现其他方法都有漏洞。没啥可说的。
Executing...
Test 1: TEST OK [0.000 secs, 11040 KB]
Test 2: TEST OK [0.000 secs, 11040 KB]
Test 3: TEST OK [0.000 secs, 11040 KB]
Test 4: TEST OK [0.000 secs, 11040 KB]
Test 5: TEST OK [0.000 secs, 11040 KB]
Test 6: TEST OK [0.000 secs, 11040 KB]
Test 7: TEST OK [0.000 secs, 11040 KB]
Test 8: TEST OK [0.000 secs, 11040 KB]
Test 9: TEST OK [0.000 secs, 11040 KB]
Test 10: TEST OK [0.054 secs, 11040 KB]
Test 11: TEST OK [0.518 secs, 11040 KB]
Test 12: TEST OK [0.119 secs, 11040 KB]
Test 13: TEST OK [0.000 secs, 11040 KB]
All tests OK.
1 /* 2 ID:wuhuaju2 3 PROG:stamps 4 LANG:C++ 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <cstdlib> 9 #include <algorithm> 10 #include <cstring> 11 #include <string> 12 using namespace std; 13 14 const int maxn=2000100; 15 int f[maxn]; 16 int a[52]; 17 int n,k,maxx; 18 19 void close() 20 { 21 fclose(stdin); 22 fclose(stdout); 23 exit(0); 24 } 25 26 void work() 27 { 28 } 29 30 void init () 31 { 32 freopen("stamps.in","r",stdin); 33 freopen("stamps.out","w",stdout); 34 scanf("%d %d",&k,&n); 35 for (int i=0;i<n;i++) 36 scanf("%d",&a[i]); 37 sort(a,a+n); 38 maxx=a[n-1]*k; 39 for (int i=1;i<=maxx;i++) 40 { 41 f[i]=100000000; 42 for (int j=0;j<n;j++) 43 { 44 if (i-a[j]>=0) //注意:此时是排好序了的! 45 f[i]=min(f[i],f[i-a[j]]+1); 46 else break; //所以可以break了! 47 } 48 } 49 for (int i=1;i<=maxx;i++) 50 if (f[i]>k) 51 { 52 cout<<i-1<<endl; 53 close(); 54 } 55 cout<<maxx<<endl;//这句话比较关键 56 } 57 58 int main () 59 { 60 init(); 61 work(); 62 close(); 63 return 0; 64 }