#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxcolor = 12;
const int volume = 50;
int n,grey;
int color[maxcolor];
int cmp(int a,int b){
return a > b;
}
int main(){
int i,j,curmax,totalset,initcolor;
while(scanf("%d",&n) && n){
curmax = -1;
memset(color,0,sizeof(color));
for(i = 0; i < n; ++i){
scanf("%d",color+i);
curmax = curmax > color[i]?curmax:color[i];
}
scanf("%d",&grey);
totalset = curmax/volume + ((curmax %volume)&1);
initcolor = totalset * volume; //每种颜色的数量
for(i = 0; i < n; ++i){
color[i] = initcolor - color[i];
}
while(grey > 0){
sort(color,color+n,cmp);
if(color[0] == 0 || color[1] == 0 || color[2] == 0){
//缺少数量最多的三种颜色
++totalset;
for(i = 0; i < n; ++i){
color[i] += 50;
}
}
--grey;
--color[0];
--color[1];
--color[2];
sort(color,color+n,cmp);
}
printf("%d\n",totalset);
}
return 0;
}
题目大意:
一套颜色里有3-12瓶,每瓶50ml,等量(xml)三种不同的颜色混合可以得到xml grey(3 * x xml颜色混合后体积不会变大), 给定一套颜色里的瓶数N和需要这N中颜色及灰色的数量,求最少需要多少套颜色?
思路:
写到这才发现这是个求最优解问题
首先,N种不能通过混合得到的颜色只能直接取得,记这N种需要数量最多的为max ml,若max % 50 == 0,则从max/50,否则从[max/50]+1得到基准套数
接着求出余下可用于混合的每种颜色,这一步就涉及greedy algorithm了
如果grey != 0
将可用于混合的量排序,然后从高到低,如果前三种都>=1ml,前三种各取1ml,配成1ml灰色;否则每种颜色增加50ml(一整套颜色),接着配grey,直到grey足够
ps:
1.poj上貌似不支持sort+stl的greater<int>()(compile error),所以就改成了cmp
2.为此还特意了解了sort的cmp函数怎么写,同时发现stl里的sort比qsort效率要高
因为qsort就是一般的快排,而sort依据数据的实际情形使用了多种排序方法,减少了退化带来的复杂度