题面
题意
有n种硬币,每种硬币的颜色不同,你想要知道每种硬币的颜色,而且你不知道一共有哪些颜色。
你知道硬币的币值,而且任意两个硬币的币值都有倍数关系。
你可以向一个取款机取任意金额,它会给你最少的硬币数量,问你至少要取几次钱才能知道每种硬币的颜色。
做法
首先要找到最优的查找方案。
要想去区分两种硬币,只能通过硬币的数量,因为可以取多次,所以每次取某种硬币的数量可以不同。对于某种硬币,我们可以通过比较几次取它的数量所构成的序列(除了0,0,0,0……)来确定它的种类。因此,如果每种硬币(除了币值最大的硬币)与比它币值大的硬币的最小币值比都为d的话,取n次最多可以辨别出d^n-1种硬币,之后的事情就简单了。
代码
#include <bits/stdc++.h>
#define ll long long
#define P pair<ll,ll>
#define mp make_pair
#define fi first
#define se second
#define N 110
using namespace std;
class ColorfulCoins
{
public:
int minQueries( vector<long long> values );
};
inline int ask(ll u,ll v)
{
int res=0;
ll t=1;
for(;t<=v;t*=u) res++;
return res;
}
int ColorfulCoins::minQueries(vector<long long> values)
{
ll n=values.size()-1,t,sum=0,i;
int need=1;
map<ll,ll>cnt;
map<ll,ll>::iterator it;
vector<P>use;
cnt.clear();
use.clear();
for(i=0; i<n; i++)
{
t=values[i+1]/values[i];
if(!cnt.count(t)) cnt[t]=1;
else cnt[t]++;
}
for(it=cnt.begin(); it!=cnt.end(); it++)
{
sum+=(*it).se;
need=max(need,ask((*it).fi,sum));
}
return need;
}