hdu5119 DP

来源:互联网 发布:淘宝卖家威胁要上门 编辑:程序博客网 时间:2024/06/06 15:36

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5119


题目大意:给你n(n<= 40)个数,取任意一些数,异或和大于等于m的情况有多少种


思路:因为ai不会超过10^6,所以可以设一个上界1<<20,枚举每一个异或值。

dp[i][j]表示前i个数异或和为j的种类数

不取a[i]时,dp[i][j] += dp[i-1][j];

取a[i]时,dp[i][j^a[i]] += dp[i-1][j];

初始状态dp[0][0] = 1;

开long long


#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <stack>#include <queue>#include <algorithm>#include <vector>#include <map>#include <set>#include <stdlib.h>#include <iomanip>#include <fstream>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define maxn 105#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define ULL unsigned long long#define FOR(i , n) for(int i = 1 ;  i<= n ; i ++)typedef pair<int , int> pii;#define INF 100000000int t , n , m;int ss = 1 << 20;int a[50];LL dp[50][1<<20];int main(){    scanf("%d" , &t);    int ncase = 1;    while(t--)    {        scanf("%d %d" , &n , &m);        for(int i = 1 ; i <= n ; i ++)        {            scanf("%d" , &a[i]);        }        mem(dp , 0);        dp[0][0] = 1;        for(int i = 1 ; i <= n ; i ++)        {            for(int j = 0 ; j < ss ; j ++)            {                dp[i][j] += dp[i-1][j];                dp[i][j^a[i]] += dp[i-1][j];            }        }        LL ans = 0;        for(int j = m ; j < ss ; j ++)        {            ans += dp[n][j];        }        printf("Case #%d: %I64d\n" , ncase ++ , ans);    }    return 0;}


0 0
原创粉丝点击