思路:
首先大于n的数肯定不能放,不断/2至小于等于n再考虑,其次对于任意小于等于n的元素,一定是能放则放,放不下就/2退位。不要想明明能放却不放,先去补更小的空位, 这样看似合理,但一定不正确,因为你去补更小的空位,本该属于你的位置就空出来了,就又得有新的元素去救,但你会发现,这个元素一定能不断/2最终变成你去补的元素,所以这就多次一举了。
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
bool st[N];
void solve()
{
memset(st, 0, sizeof st);
int n;
cin>>n;
int cnt=0;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
while(x>n) x/=2;
while(x)
{
if(!st[x])
{
st[x]=true;
cnt++;
break;
}
x/=2;
}
}
if(cnt!=n) puts("NO");
else
puts("YES");
}
int main()
{
int _;
cin>>_;
while(_--) solve();
return 0;
}