题目来源:[NWPU][2014][TRN][5]二分和贪心 M题
http://vjudge.net/contest/view.action?cid=49586#problem/M
作者:npufz
题目大意:给定颜料包的颜色的总的种类数N,给定与颜料包里颜色一一对应的各种颜料的需求量,最后还有一种灰色的颜料必须自己调制得到,每个颜料包的颜色有3~12种,具 体数目由测试数据给出,调制灰色的颜料需要任意三种不同的颜色的颜料搭配才可以,并且个颜料包里有所含的每种颜料各50ML,调制灰色的颜料时体积不会增加,即 三种不同的颜色各1ML可以调制1ML 粘稠的灰色颜料,输入数据包括所选择的颜料包的大小,即颜料包所包含的颜色有几种,以及对应颜料包里的各个颜色所需的体 积,还包括所需的灰色颜料的体积,均已ML计量,求出满足需求的最少的买几包颜料包
代码:
#include <cstdio>
#include<iostream>
using namespace std;
int main()
{int n,a[12],g,gy,i,j,k,b[12],t,sum;
while(scanf("%d",&n),n)
{ for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<12;i++) b[i]=0;
scanf("%d",&g);
for(i=0;i<n-1;i++)
{k=i;
for(j=i+1;j<n;j++)
if(a[j]<a[k]) k=j;
if(i!=k){t=a[i];a[i]=a[k];a[k]=t;}}
sum=0;
if(a[n-1]%50==0) sum=sum+a[n-1]/50;
else sum=(sum+1+a[n-1]/50);
for(i=0;i<n;i++)
b[i]=sum*50-a[i];
gy=0;
while(gy<g)
{ while(b[3]>0)
{ gy+=(b[2]-b[3]+1);
b[0]=b[0]-b[2]+b[3]-1;
b[1]=b[1]-b[2]+b[3]-1;
b[2]=b[3]-1;
for(i=0;i<n-1;i++)
{k=i;
for(j=i+1;j<n;j++)
if(b[j]>b[k]) k=j;
if(i!=k){t=b[i];b[i]=b[k];b[k]=t;}}}
gy+=b[2];
b[0]-=b[2];
b[1]-=b[2];
b[2]=0;
if(gy<g)
{ sum++;
for(i=0;i<n;i++)
b[i]+=50;}}
cout<<sum<<endl;
}
return 0;
}
反思:一开始根据已知的各个颜色的颜料的体积,求能配制的灰色颜料的体积的最大的值时,策略错误,后来发现应该先把体积最多的三种颜料各拿来一毫升配制一毫升灰色的 颜料,然后再重复同样的策略对剩下的进行这个操作,直到不能再次配制,这样就使配制的为最多的,就搞定了,贪心在于每次都找到当前最优的选择,并且如果当前不选 择这些最优的操作,所得的最终的结果不可能比当前选择最优的操作更优