HDU 5119 Happy Matt Friends(DP || 高斯消元)

时间:2024-01-02 15:55:32

题目链接

题意 : 给你n个数,让你从中挑K个数(K<=n)使得这k个数异或的和小于m,问你有多少种异或方式满足这个条件。

思路 : 正解据说是高斯消元。这里用DP做的,类似于背包,枚举的是异或的和,给定的数你可以选择放或者不放,dp[i][j]代表的是前 i 个数中选择k个异或的和为j。

 #include <stdio.h>
#include <string.h>
#include <iostream>
#define LL long long
using namespace std ;
int a[] ;
LL dp[][ << ] ;
int main()
{
int T,n,m,casee = ;
scanf("%d",&T) ;
while(T--)
{
scanf("%d %d",&n,&m) ;
for(int i = ; i < n ; i++)
scanf("%d",&a[i]) ;
memset(dp,,sizeof(dp)) ;
dp[][] = ;
LL ans = ;
if(m == ) ans++ ;
for(int i = ; i < n ; i++)
{
for(int j = ; j < ( << ) ; j++)
{
if(dp[i][j] == ) continue ;
dp[i+][j] += dp[i][j] ;
int temp = j ^ a[i] ;
dp[i+][temp] += dp[i][j] ;
if(temp >= m)
{
ans += dp[i][j] ;
}
}
}
printf("Case #%d: %I64d\n",casee++,ans) ;
}
return ;
}