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

题目描述

农夫约翰要量取 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

说明

题目翻译来自NOCOW。

USACO Training Section 5.3

搜索,或dp,或搜索+dp

#include<cstdio>
#include<algorithm>
inline int read() {
    int x=0;
    char c=getchar();
    while(c<‘0‘||c>‘9‘)c=getchar();
    while(c<=‘9‘&&c>=‘0‘)x=x*10+c-‘0‘,c=getchar();
    return x;
}
const int maxn = 107;
int p,n;
int po[maxn],ans=0x7fffffff,pos_ans[maxn],tmp[maxn];
void update(int x) {
    ans=x;
    for(int i=1;i<=x;++i) pos_ans[i]=tmp[i];
}
void dfs(int x,int y,int z){//第x个桶,剩余流量y,已经买了z
    if(x>n)return;
    if(z>ans)return;
    tmp[z]=po[x];
    if(y%po[x]==0) {
        if(z>ans)return;
        if(z<ans){update(z);return;}
        for(int i=1;i<=z;++i) {
            if(tmp[i]<pos_ans[i]) {
                update(z);
                break;
            }
            else if(tmp[i]>pos_ans[i])break;
        }
        return ;
    }
    for(int i=po[x];i+po[x]<y;i+=po[x])dfs(x+1,y-i,z+1);
    dfs(x+1,y,z);
}
int main() {
    p=read(),n=read();
    for(int i=1;i<=n;++i) po[i]=read();
    std::sort(po+1,po+n+1);
    dfs(1,p,1);
    printf("%d ",ans);
    for(int i=1;i<=ans;++i) {
        printf("%d ",pos_ans[i]);
    }
    return 0;
}
时间: 2025-01-06 21:32:09

luogu P2744 [USACO5.3]量取牛奶Milk Measuring的相关文章

[IDDFS+背包] 洛谷P2744 [USACO5.3]量取牛奶Milk Measuring

折腾了好几天的题目,简单讲讲心得. 首先看了题解才写出来的,因为有一个核心的一点没想到,用桶的数量当 迭代加深搜索的层数,算是长见识了~ 每次dp数组的初始化自己手动赋值0,不然会TLE一个点. 思路: 以桶的数量作为深度,做IDDFS,每次用背包DP判断当前是否可行.在一定有解的情况下,那么这个思路是一定能求出答案的(这不是屁话吗? #include <cstdio> #include <algorithm> #include <cstring> int q,n,bu

[USACO5.3]量取牛奶Milk Measuring

https://daniu.luogu.org/problemnew/show/P2744 滚动数组压去第一维:前i种木桶 f[j] 量取体积j最少需要几种木桶 g[j]  体积j的最优解是否使用了第i种木桶 f[j]= f[j-a[i]] +  g[j-a[i]]^1 输出方案时用搜索,DP检验 g[j] 表示用当前搜索的木桶方案,能否量取体积j g[j]|=g[j-a[i]] 先对木桶按大小排一次序 搜索的时候从前往后选,第一个合法的方案满足字典序最小 #include<cstdio> #

luogu P1215 [USACO1.4]母亲的牛奶 Mother&#39;s Milk

题目描述 农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的.有时,农民把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了.当然每一次灌注都是完全的.由于节约,牛奶不会有丢失. 写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性. 输入输出格式 输入格式: 单独的一行包括三个整数A,B和C. 输出格式: 只有一行,升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性. 输入输出样例 输入样例#1:

母亲的牛奶(milk) (BFS)

问题 A: 母亲的牛奶(milk) 时间限制: 1 Sec  内存限制: 64 MB提交: 14  解决: 8[提交][状态][讨论版] 题目描述 农民约翰有三个容量分别是A.B.C升的桶,A.B.C分别是三个从1到20的整数,最初,A和B桶都是空的,而C桶是装满牛奶的.有时,约翰把牛奶从一 个桶倒到另一个桶中,直到被灌桶装满或原桶空了.当然每一次灌注都是完全的,由于节约,牛奶不会丢失.写一个程序去帮助约翰找出当A桶是空的时候,C桶中 牛奶所剩量的所有可能性. 输入 单独的1行,包括三个整数A,

母亲的牛奶(milk)

母亲的牛奶(milk) 题目描述 农民约翰有三个容量分别是A.B.C升的桶,A.B.C分别是三个从1到20的整数,最初,A和B桶都是空的,而C桶是装满牛奶的.有时,约翰把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了.当然每一次灌注都是完全的,由于节约,牛奶不会丢失.写一个程序去帮助约翰找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性. 输入 单独的1行,包括三个整数A,B和C. 输出 只有1行,列出当A桶是空的时候,C桶牛奶所剩量的所有可能性. 样例输入 8 9 10 样例输出 1 2

USACO 5.3 Milk Measuring

Milk MeasuringHal Burch Farmer John must measure Q (1 <= Q <= 20,000) quarts of his finest milk and deliver it in one big bottle to a customer. He fills that bottle with exactly the number of quarts that the customer orders. Farmer John has always b

USACO Section 5.3 Milk Measuring (IDDFS+dp)

迭代加深搜索,从小到大枚举桶数的上限maxd:对每个maxd,枚举每个组合,判断是否能够倒出q:直到得到answer.判断的部分就用dp(完全背包). ------------------------------------------------------------------------- #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #includ

PowerShell 运维菜鸟系列-02-批量取n台Windows KEY(2018年大年初一奉献)

系列博文: PowerShell 运维菜鸟系列-01-批量为n台服务器导入PFX证书(2017年除夕奉献) http://blog.51cto.com/dynamic/2071716 项目场景: 2017年,某客户忽然来电:"我们单位正在查正版,我想知道所有加域的Windows电脑的激活KEY分别是什么?". 详细需求: 1. 操作系统版本 Windows XP.Windows 7.Windows 10.Windows Server 2003.Windows Server 2008 R

【Luogu】P1758 [NOI2009] 管道取珠

终于开始正式写了.... 题目描述 管道取珠是小X很喜欢的一款游戏.在本题中,我们将考虑该游戏的一个简单改版.游戏画面如图1所示: (图1) 游戏初始时,左侧上下两个管道分别有一定数量的小球(有深色球和浅色球两种类型),而右侧输出管道为空.每一次操作,可以从左侧选择一个管道,并将该管道中最右侧的球推入右边输出管道. 例如:我们首先从下管道中移一个球到输出管道中,将得到图2所示的情况. (图2) 假设上管道中有n个球, 下管道中有m个球,则整个游戏过程需要进行n+m次操作,即将所有左侧管道中的球移