题目描述

农夫约翰要量取 Q(1 <= Q <= 20,000)夸脱(夸脱,quarts,容积单位——译者注) 他的最好的牛奶,并把它装入一个大瓶子中卖出。消费者要多少,他就给多少,从不有任何误差。

农夫约翰总是很节约。他现在在奶牛五金商店购买一些桶,用来从他的巨大的牛奶池中量出 Q 夸脱的牛奶。每个桶的价格一样。你的任务是计算出一个农夫约翰可以购买的最少的桶的集合,使得能够刚好用这些桶量出 Q 夸脱的牛奶。另外,由于农夫约翰必须把这些桶搬回家,对于给出的两个极小桶集合,他会选择“更小的”一个,即:把这两个集合按升序排序,比较第一个桶,选择第一个桶容积较小的一个。如果第一个桶相同,比较第二个桶,也按上面的方法选择。否则继续这样的工作,直到相比较的两个桶不一致为止。例如,集合 {3,5,7,100} 比集合 {3,6,7,8} 要好。

为了量出牛奶,农夫约翰可以从牛奶池把桶装满,然后倒进瓶子。他决不把瓶子里的牛奶倒出来或者把桶里的牛奶倒到别处。用一个容积为 1 夸脱的桶,农夫约翰可以只用这个桶量出所有可能的夸脱数。其它的桶的组合没有这么方便。

计算需要购买的最佳桶集,保证所有的测试数据都至少有一个解。

输入输出格式

输入格式:

Line 1: 一个整数 Q

Line 2: 一个整数P(1 <= P <= 100),表示商店里桶的数量

Lines 3..P+2: 每行包括一个桶的容积(1 <= 桶的容积 <= 10000)

输出格式:

输出文件只有一行,由空格分开的整数组成:

为了量出想要的夸脱数,需要购买的最少的桶的数量,接着是:

一个排好序的列表(从小到大),表示需要购买的每个桶的容积

输入输出样例

输入样例#1:

16

3

3

5

7

输出样例#1:

2 3 5

【题解】

这是一道背包动态规划与搜索结合的题目,由小到大DFS搜取桶个数,背包动态规划(完全背包)来判断K个桶是否

能能测体积为V的牛奶。

相比于其他题解,我的注释貌似更详尽,我的程序貌似更易懂。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int a[101],use[101],v,n,k;
void print()
{
printf("%d ",k);
for (int i=1;i<=k;i++)
printf("%d ",a[use[i]]);
exit(0);//输完情况直接跳回主函数
}
void dp()//完全背包,判断取K个桶时能否取到体积为V的情况(转化:K个桶即为K种物品,每种物品有无限个,体积为背包容积,原来的最大价值由于不用管,存是否可行就行了)
{
int f[20010];
memset(f,0,sizeof(f));
f[0]=1;//f[i]指体积为i时是否能取到(用bool类型等效)
for (int i=1;i<=k;i++)
for (int j=1;j<=v/a[use[i]];j++)
f[j*a[use[i]]]=1;//先初始化,表明能取到体积为一个桶体积的倍数的情况(==1)
for (int i=1;i<=k;i++)
for (int j=a[use[i]];j<=v;j++)//use[i]记录取第i个桶时取到桶的编号(只在取k个桶的情况内有效)
f[j]=f[j]||f[j-a[use[i]]];//如果||两边情况有一种情况取得到(==1)就能取到体积为j那种情况
if (f[v]==1)//一取到要求的体积就输出(保证字典序最小)
print();
}
void dfs(int dep)//枚举取K个桶时取哪几个桶
{
for (int i=use[dep-1]+1;i<=n-k+dep;i++)//下一次递归就是上次取到的桶的下一个开始,多取一个桶,
//i的最大范围实际是为后面搜(k-dep)个桶留有起码的空间(后面每个i都取一个桶)
{
use[dep]=i;
if (dep==k)//直到取到k个桶为止
dp();
else
dfs(dep+1);
}
}
void fenzu()//枚举取K个桶的情况,由于是从小到大搜,可以保证搜到的第一个情况为取的个数最小的情况
{
for (k=1;k<=n;k++)
dfs(1);
}
int main()
{
int i;
//freopen("milk.in","r",stdin);
//freopen("milk.out","w",stdout);
scanf("%d",&v);
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
fenzu();
//fclose(stdin);
//fclose(stdout);
return 0;
}

洛谷P2744 [USACO5.3]量取牛奶Milk Measuring的更多相关文章

  1. 洛谷 P2744 [USACO5.3]量取牛奶Milk Measuring

    P2744 [USACO5.3]量取牛奶Milk Measuring 题目描述 农夫约翰要量取 Q(1 <= Q <= 20,000)夸脱(夸脱,quarts,容积单位——译者注) 他的最 ...

  2. luogu P2744 [USACO5.3]量取牛奶Milk Measuring

    题目描述 农夫约翰要量取 Q(1 <= Q <= 20,000)夸脱(夸脱,quarts,容积单位——译者注) 他的最好的牛奶,并把它装入一个大瓶子中卖出.消费者要多少,他就给多少,从不有 ...

  3. 【洛谷2744 】【CJOJ1804】[USACO5.3]量取牛奶Milk Measuring

    题面 Description 农夫约翰要量取 Q(1 <= Q <= 20,000)夸脱(夸脱,quarts,容积单位--译者注) 他的最好的牛奶,并把它装入一个大瓶子中卖出.消费者要多少 ...

  4. [USACO5.3]量取牛奶Milk Measuring

    https://daniu.luogu.org/problemnew/show/P2744 滚动数组压去第一维:前i种木桶 f[j] 量取体积j最少需要几种木桶 g[j]  体积j的最优解是否使用了第 ...

  5. [luoguP1494] 岳麓山上打水 && [luoguP2744] [USACO5.3]量取牛奶Milk Measuring

    传送门 传送门 dfs选取集合,dp背包判断 虽然我觉的会TLE.. 但是的确是AC了 #include <cstdio> #include <cstring> #includ ...

  6. [USACO Section 5.3]量取牛奶 Milk Measuring (动态规划,背包$dp$)

    题目链接 Solution 完全背包 \(dp\) , 同时再加一个数组 \(v[i][j]\) 记录当总和为\(j\) 时第 \(i\) 种物品是否被选. 为保证从小到大和字典序,先将瓶子按大小排序 ...

  7. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码

    洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...

  8. 洛谷 P4018 Roy&October之取石子

    洛谷 P4018 Roy&October之取石子 题目背景 Roy和October两人在玩一个取石子的游戏. 题目描述 游戏规则是这样的:共有n个石子,两人每次都只能取 p^kpk 个(p为质 ...

  9. [洛谷P1709] [USACO5.5]隐藏口令Hidden Password

    洛谷题目链接:[USACO5.5]隐藏口令Hidden Password 题目描述 有时候程序员有很奇怪的方法来隐藏他们的口令.Binny会选择一个字符串S(由N个小写字母组成,5<=N< ...

随机推荐

  1. Redis系列(十)--集群cluster

    在之前学习了Master-Slave.Sentinel模式,但是在某些情况下还是无法满足系统对QPS等要求,这时候就需要Cluster,Redis3.0支持了cluster 一.为什么使用Cluste ...

  2. java虚拟机(三)--HotSpot 对象

    普通对象的创建(不包括数组和class对象): 当虚拟机遇到new指令时,会在常量池中检查是否包含这个类的符号引用(全限定名),通过这个确定是否经过类加载的过程,如果true,为该 对象分配内存,对象 ...

  3. JS中的let和var的区别

    最近很多前端的朋友去面试被问到let和var的区别,其实阮一峰老师的ES6中已经很详细介绍了let的用法和var的区别.我简单总结一下,以便各位以后面试中使用. ES6 新增了let命令,用来声明局部 ...

  4. 03Servlet API

    Servlet API Servlet是实现javax.servlet.Servlet接口的对象.大多数Servlet通过从GenericServlet或HttpServlet类进行扩展来实现.Ser ...

  5. wpf 自定义Button按钮

    创建ButtonEx类 public class ButtonEx : Button { static ButtonEx() { DefaultStyleKeyProperty.OverrideMet ...

  6. JAVA基础——链表结构之双端链表

    双端链表:双端链表与传统链表非常相似.只是新增了一个属性-即对最后一个链结点的引用 如上图所示:由于有着对最后一个链结点的直接引用.所以双端链表比传统链表在某些方面要方便.比如在尾部插入一个链结点.双 ...

  7. libevent reference Mannual IV --Helper functions and types

    FYI: http://www.wangafu.net/~nickm/libevent-book/Ref5_evutil.html Helper functions and types for Lib ...

  8. Storm 开箱笔记

    目录 Storm 开箱 1. 什么是 Storm 2. Hello World(WordCountTopology) 3. 常用API 4. 基本概念 5. 流分组策略 6. 并行度 7. Acker ...

  9. Object类型转换为String类型

    1. Object.toString() 1 obj.toString() 注意:必须保证Object不是null值,否则将抛出NullPointerException异常. 2. (String)O ...

  10. Python面向对象,析构继承多态

    析构: def __del__(self): print("del..run...") r1 = Role("xx") del r1 结果打印del..run. ...