-------------------------------------------------------------------------
分析:
核心思想,尽可能把少的颜色用完并且每组只用一个,尽可能把多的颜色用掉每组两个来配对。
就是尽可能的全用完,如果用不完就找受到限制的原因所能取得的最大值。
(1)
是什么颜色不重要,先对颜色的数量排序 得到 color[3] (从小到大)
首先优先把最少的颜色用完(最少的颜色一定会被用完,因为color[1]+color[2]>=2*color[0]恒成立)
得到 ans+=color[0]。
然后考虑从 color[1]和color[2]中减掉 2*color[0]个用于组成上述的情况把color[0]组完。
具体扣除color[1]和color[2]中分别哪些用来和 color[0]配对暂时先不管(因为后面考虑的情况剩下的就是用来配对这个的)。
(2)
那么剩下的总数还有 color[1]+color[2]-2*color[0] (减掉的 2*color[0]用来配对color[0])
这时为了让这两种颜色组出最多的组数
<1>假设完全够配对,剩下的全部用完,就能组成 (color[1]+color[2]-2*color[0])/3 组。
<2>但是可能第三种颜色很多第二种颜色不够,那么最多能组成的数量就是 第二少的颜色数量 color[1]
总结:剩下的数量能组成的个数就是 假设完全配对 和 颜色不够配对时 较小的一个
ans+=min((color[1]+color[2]-2*color[0])/3 ,color[1])
那么就得到了常数级时间复杂度
AC代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
vector<long long >color;
long long ans=0,temp;
for(int i=0;i<3;++i)
{
cin>>temp;
color.push_back(temp);
}
sort(color.begin(),color.end());
ans+=color[0]; //关键部分,见上述分析
ans+=min((color[1]+color[2]-2*color[0])/3,color[1]); //关键部分,见上述分析
cout<<ans<<endl;
}
return 0;
}