【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 }

 

转载于:https://www.cnblogs.com/hoskey/p/3807065.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值