首页 > 代码库 > 【USACO 3.1.6】邮票
【USACO 3.1.6】邮票
【描述】
已知一个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。
【格式】
PROGRAM NAME: stamps
INPUT FORMAT:(file stamps.in)
第1行: | 两个整数,K和N。K(1 <= K <= 200)是可用的邮票总数。N(1 <= N <= 50)是邮票面值的数量。 |
第2行..文件末: | N个整数,每行15个,列出所有的N个邮票的面值,面值不超过10000。 |
OUTPUT FORMAT:(file stamps.out)
单独的一行,一个整数,从 1 分开始连续的可用集合中不多于 K 张邮票贴出的邮资数。
【分析】
普通的DP,注意审题。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 const int maxn=50+10; 7 const int INF=200+10; 8 using namespace std; 9 int S[maxn],f[2000000+10];10 int main()11 {12 int k,n,i,j;13 //文件操作14 freopen("stamps.in","r",stdin);15 freopen("stamps.out","w",stdout);16 scanf("%d%d",&k,&n);17 for (i=1;i<=n;i++) scanf("%d",&S[i]);18 f[0]=0;19 for (i=1;i<=2000000;i++)20 {21 f[i]=INF;22 for (j=1;j<=n;j++) if (i-S[j]>=0) f[i]=min(f[i],f[i-S[j]]+1);23 if (f[i]>k) break;24 }25 printf("%d",i-1);26 return 0;27 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。