题目翻译:
杂货店出售一种由 N(3<=N<=12)种不同颜色的颜料,每种一瓶(50ML),
组成的颜料套装。你现在需要使用这 N 种颜料;不但如此,你还需要一定
数量的灰色颜料。杂货店从来不出售灰色颜料——也就是它不属于这 N 种
之一。幸运的是,灰色颜料是比较好配置的,如果你取出三种不同颜色的
颜料各 x ml,混合起来就可以得到 xml 的灰色颜料(注意不是 3x)。
现在,你知道每种颜料各需要多少 ml。你决定买尽可能少的“颜料套装”,
来满足你需要的这 N+1 种颜料。那么你最少需要买多少个套装呢?输入包含若干组测试数据。每组数据一行:第一个数 N, 3<=N<=12, 含
义如上;接下来 N+1 个数,分别表示你需要的 N+1 种颜料的毫升数。
最后一种是灰色。所有输入的毫升数<=1000.
做法是: 先把每种颜料买好,再来制作灰色颜料,我们每次选颜料最多的三种,一个一个的制作灰色颜料,这样得到的答案是最优的,那么实现方法可以有两种,一个是用sort排序,一个是用优先队列。
sort版:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
int a[50];
int main()
{
int n,f1;
while(scanf("%d",&n)!=0)
{
if(n == 0)
break;
int maxn = 0,ans=0,f1=0;
for(int i = 1; i <= n; i ++)
{
scanf("%d",&a[i]);
maxn = max(maxn,a[i]);
}
cin>>a[n+1];
if((maxn%50) == 0)
{
f1 = maxn/50;
}
else f1 = maxn/50+1;
for(int i = 1; i <= n; i ++)
{
a[i] = (f1*50-a[i]);
q.push(a[i]);
}
sort(a+1,a+n+1);
while(a[n+1] > 0)
{
while(a[n-2] > 0)
{
a[n]--;
a[n-1]--;
a[n-2]--;
a[n+1]--;
sort(a+1,a+n+1);
}
for(int i = 1; i <= n; i ++)
{
a[i] = a[i] + 50;
}
if(a[n+1] > 0)
ans ++;
}
printf("%d\n",ans+f1);
}
return 0;
}
优先队列版:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
int a[50];
int main()
{
priority_queue<int>q;
int n,f1;
while(scanf("%d",&n)!=0)
{
if(n == 0)
break;
int maxn = 0,ans=0,f1=0;
for(int i = 1; i <= n; i ++)
{
scanf("%d",&a[i]);
maxn = max(maxn,a[i]);
}
cin>>a[n+1];
if((maxn%50) == 0)
{
f1 = maxn/50;
}
else f1 = maxn/50+1;
for(int i = 1; i <= n; i ++)
{
a[i] = (f1*50-a[i]);
q.push(a[i]);
}
while(a[n+1] > 0)
{
int x = q.top();
q.pop();
int x1 = q.top();
q.pop();
int x2 = q.top();
q.pop();
while(x2 > 0)
{
x--;x1--;x2--;
a[n+1]--;
q.push(x);
q.push(x1);
q.push(x2);
x = q.top();q.pop();
x1 = q.top();q.pop();
x2 = q.top();q.pop();
}
q.push(x);
q.push(x1);
q.push(x2);
for(int i = 1; i <= n; i ++)
{
int y = q.top();
a[i] = y+50;
q.pop();
}
for(int i = 1; i <= n; i ++)
q.push(a[i]);
if(a[n+1] > 0)
ans ++;
}
printf("%d\n",ans+f1);
while(!q.empty())
q.pop();
}
return 0;
}