把大小为n的集合S分成k个子集,使得每个子集的子集和相等,即 Si = average(S)
对于n=6,k=3, 1,2,3,3,4,5,第一个子集可能会选择(1,2,3),导致其他子集无法拼凑成功,这就意味着可能需要回溯
而实际上回溯搜索肯定会 爆
所以应该从大到小的进行选择。因为大的可以被拆成小的,如果 5 无法跟其他数 拼凑成平均数,那2,3也肯定不可以
最后注意一个所有值都为0且k>n的情况
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
#define INF 1e9
#define maxn 25
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define mset(x) memset(x,0,sizeof(x))
typedef long long ll;
int t, n, k;
ll a[maxn];
bool vis[maxn];
ll avg;
bool dfs(int pos, int lev){
while(vis[pos] && pos>0)
pos--;
if(pos==0 && lev)
return 0;
if(lev<0)
return 0;
if(lev==0)
return 1;
if(dfs(pos-1, lev-a[pos])){
vis[pos] = 1;
return 1;
}
return dfs(pos-1, lev);
}
int main(){
// freopen("a.txt","r",stdin);
// freopen(".out","w",stdout);
cin>>t;
while(t--){
cin>>n>>k;
mset(vis);
ll sum=0;
rep(i,1,n){
scanf("%lld", &a[i]);
sum += a[i];
}
if(sum % k != 0){ puts("no"); continue; }
if(k>n){ puts("no"); continue; }
avg = sum/k;
sort(a+1, a+1+n);
if(a[n] > avg){ puts("no"); continue; }
bool ans = 1;
rep(i,1,k)
{
if(!dfs(n, avg)){
ans=0;
break;
}
}
if(ans) puts("yes");
else puts("no");
}
return 0;
}