给一组邮票n张,每张价值为v,以及最多使用的邮票的数量k,求能组合成的最长的连续的邮票价值数。
这是一道很经典的题目,一老师在讲具体数学的时候说有O(1)的算法,不过要下节课才能听到。
我用的是完全背包,代码较为简洁,时间还可以(最坏情况也保持在了1s以内),不过内存用了不少。
USER: millky wang [ts_mill1]
TASK: stamps
LANG: C++
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.022 secs, 2844 KB]
Test 2: TEST OK [0.000 secs, 2848 KB]
Test 3: TEST OK [0.011 secs, 2848 KB]
Test 4: TEST OK [0.000 secs, 2844 KB]
Test 5: TEST OK [0.000 secs, 2848 KB]
Test 6: TEST OK [0.000 secs, 2844 KB]
Test 7: TEST OK [0.011 secs, 2844 KB]
Test 8: TEST OK [0.000 secs, 2852 KB]
Test 9: TEST OK [0.011 secs, 2904 KB]
Test 10: TEST OK [0.086 secs, 5448 KB]
Test 11: TEST OK [0.940 secs, 10528 KB]
Test 12: TEST OK [0.173 secs, 8928 KB]
Test 13: TEST OK [0.000 secs, 2920 KB]
- /*
- ID: millky
- PROG: stamps
- LANG: C++
- */
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <cmath>
- #include <cstdio>
- #include <algorithm>
- #include <vector>
- #include<iomanip>
- using namespace std;
- int *p;
- int k,n,v,value[50];
- int main()
- {
- int temp,t;
- freopen("stamps.in","r",stdin);
- freopen("stamps.out","w",stdout);
- scanf("%d%d",&k,&n);
- for (int i=0;i<n;++i)scanf("%d",value+i);
- temp=*max_element(value,value+n);
- v=temp*k+1;
- p=new int[v];
- p[0]=0;
- for (int i=1;i<v;++i) p[i]=-1;
- for(int i=0;i<n;++i) for (int j=value[i];j<v;++j)
- {
- t=j-value[i];
- if (p[t]>-1 && p[t]<k)
- {
- if(p[j]<0) p[j]=1+p[t];
- else p[j]=min(p[j],1+p[t]);
- }
- }
- for (temp=1;temp<v && p[temp]>0;++temp);
- printf("%d/n",temp-1);
- return 0;
- }