看数一巨巨的博客写的,,,准备开始学DP了,是不是很晚···,这个题的有点像背包,状态转移还是很好写的,主要注意初始化的地方
#include<iostream>
#include<cstdio>#include<string.h>
#include<string>
#include<set>
#include<algorithm>
#include<cmath>
#define ll __int64
#define MAX 1000009
using namespace std;
int a[50];
ll dp[50][1<<20];//dp[i][j]的含义 表示用了i个数结果是j的方案数
//转移方程 dp[i][j] += dp[i-1][j]; dp[i][j^a[i]] += dp[i-1][j];
int main()
{
int cas = 1;
int n,m,t;
ll cot;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = 0;i<n;i++)
{
scanf("%d",&a[i]);
}
memset(dp,0,sizeof(dp));
dp[0][a[0]] = 1;//用了0个数 得数为a[0]的方案数为1
dp[0][0] = 1;//规定0 得数为0的方案数为1
for(int i = 1;i<=n;i++)
{
for(int j = 0;j<1<<20;j++)
{
dp[i][j]+=dp[i-1][j];//i个方案得出j的等于前i-1的方案得出j的和
dp[i][j^a[i]]+=dp[i-1][j];//j^a[i]的方案数等于前i-1个等于j的方案数+本身
}
}
cot = 0;
for(int i = 1<<20-1;i>=m;i--)
{
cot+=dp[n-1][i];
}
printf("Case #%d: %I64d\n",cas++,cot);
}
return 0;
}