n个人,每个人手上有一个数ai。
将这些人分成若干组,组没有编号,要求每组人手上的数字之和都是质数。
求合法的分组方案数。
Input
第一行一个正整数T(1≤T≤5),表示测试数据的组数。
每组数据第一行一个正整数n(1≤n≤15)。
每组数据第二行n个正整数a1,a2,…,an(1≤ai≤100)。
Output
每组数据输出一行一个整数,即合法的分组方案数。
Sample Input
1
3
3 2 5
Sample Output
3
#include<bits/stdc++.h>
using namespace std;
const int MXS=(1<<15)+5;
const int MXN=17;
int n,a[MXN],dp[MXS],sum[MXS]={0};
int c[MXS],p[1700]={1,1};
int main(){
int t,x;
for(int i=0;i<15;i++)c[1<<i]=i+1;//初始化
//埃氏筛,在数据少的情况就不用线性筛打表了
for(int i=2;i<=850;i++)
for(int j=i<<1;j<1700;j+=i)p[j]=1;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
x=(1<<n)-1;
for(int i=1;i<=x;i++){//枚举
int t1=-i&i,t2=i^t1;//t1是最后一位1,t2是去掉之后剩余的
if(t1==i)sum[i]=a[c[i]];//单个
else sum[i]=sum[t1]+sum[t2];//多个
dp[i]=p[sum[i]]==0;
for(int j=t2;j>0;j=(j-1)&t2)//枚举
dp[i]+=dp[j]*(p[sum[j^i]]==0);//都是质数才加一
}
printf("%d\n",dp[x]);
}
return 0;
}