这道题果然质量(防AK了………………)
混合调酒(d.cpp,1s,256MB)
【描述】
酒吧里有 k 种鸡尾酒,每种的酒精含量(体积分数)为 ai/1000 。你想喝到酒精含量为 n/1000 的酒,因此你想要把一些鸡尾酒混合起来以达到目的。混合后酒精含量的定义为所有参与混合的鸡尾酒中酒精的体积和除以所有参与混合的鸡尾酒的体积和。你想知道最少需要购买多少杯鸡尾酒才能满足条件。假设每种鸡尾酒都无限供应,每杯酒的体积都是相同的。
【输入】
第一行两个整数n,k,意义如上所述。
第二行k个整数a_i,表示每种酒的酒精含量。不同酒的酒精含量可能相同。
【输出】
一行一个整数,表示至少需要购买的鸡尾酒杯数。如果无法满足条件,输出-1。
【样例输入】
50 2
100 25
【样例输出】
3
【样例解释】
购买1杯第一种鸡尾酒,2杯第二种鸡尾酒,混合起来即可。
【限制与约定】
对于30%的数据,k<=2。
对于100%的数据,0<=n,a_i<=1000,1<=k<=100000。
思考
假设共用了m杯酒,酒精含量分别为
b1,b2...bm
b1+...+bm=m∗n
b1+...+bm=n+n+...+n(m个)
(b1−n)+(b2−n)+...+(bm−n)=0
即:将所有的酒精含量减去n后,寻找最少的数字使他们的和为0
我们把数字和
(−1000到1000)
当作节点,可以使用的酒精含量当作边(边权为1),跑从0到0的最短路(也就是bfs)即可。注意显然存在一条任何时候数字和绝对值不超过1000的路径,所以(如果有解)一定能找到解。
看起来很难,然而代码简单得一匹…………我是蒟蒻。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 2010
bool v[maxn],a[maxn];
int n,k,d[maxn];
int sta[maxn];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1; i<=k; i++)
{
int p; scanf("%d",&p);
a[p]=true;
}
memset(d,0x3f,sizeof(d));
d[1005]=0;
int ta=1,fr=1; sta[1]=1005;
while(ta<=fr)
{
int cur=sta[ta++];
int cd=d[cur];
for(int i=0; i<=1000; i++)
if(a[i])
{
int re=i-n;
if(cur+re>0 && cur+re<2007 && !v[cur+re])
{
v[cur+re]=true;
d[cur+re]=cd+1;
sta[++fr]=cur+re;
}
}
}
if(d[1005]==0) puts("-1");
else printf("%d\n",d[1005]);
return 0;
}
由于边权为1,所以bfs就行了。