链接:点击打开链接
题意:有N个人,每个人有一个权值,挑选一些人人并将他们的权值异或,求最后得到的值大于M的取法有多少种
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
long long v[50],dp[2][(1<<20)+5];
int main(){
long long n,m,i,j,t,cas,ans;
scanf("%I64d",&t);
for(cas=1;cas<=t;cas++){ //因为求的是大于等于m的
scanf("%I64d%I64d",&n,&m); //数目,因此需要先规定一
for(i=1;i<=n;i++) //个上界,这个上界就是2^20
scanf("%I64d",&v[i]);
memset(dp,0,sizeof(dp));
dp[0][0]=1; //dp[i][j]表示状态是i时,
for(i=1;i<=n;i++) //异或值是j时的数量,因此
for(j=0;j<(1<<20);j++) //很容易推出转移方程
dp[i%2][j]=dp[(i-1)%2][j]+dp[(i-1)%2][j^v[i]];
ans=0; //因为第二维特别大,因此用
for(i=m;i<(1<<20);i++) //滚动数组
ans+=dp[n%2][i];
printf("Case #%I64d: %I64d\n",cas,ans);
}
return 0;
}