G - Games
题意:给定n个数字,求从中拿至多d个数子,异或和为x的方法数。
题解:计算方案数,应该想到是计数dp的......
状态:表示从前个数字中取个数字的异或和为的方案数。
状态转移方程:
空间复杂度是太大,所以借助01背包的思想,优化掉第一维,具体还要自己思考哦!!!
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 1030;
const int mod = 1e9+7;
int n, d;
ll dp[11][maxn], a[maxn];
int main()
{
//freopen("in.txt", "r", stdin);
int t; scanf("%d", &t);
while(t--) {
memset(dp, 0, sizeof(dp));
scanf("%d%d", &n, &d); if(d>n) d = n;
ll x = 0, ans = 0;
for(int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
x ^= a[i];
}
dp[0][0] = 1ll;
for(int i = 1; i <= n; i++)
for(int j = i > d ? d : i; j >= 1; j--)
for(int k = 0; k <= 1024; k++)
dp[j][k] = (dp[j][k] + dp[j-1][k^a[i]])%mod;
for(int i = 0; i <= d; i++) ans = (ans+dp[i][x])%mod;
printf("%lld\n", ans);
}
return 0;
}