zoukankan      html  css  js  c++  java
  • HDU 5119 Happy Matt Friends (14北京区域赛 类背包dp)

    Happy Matt Friends

    Time Limit: 6000/6000 MS (Java/Others)    Memory Limit: 510000/510000 K (Java/Others)
    Total Submission(s): 5188    Accepted Submission(s): 1985


    Problem Description
    Matt has N friends. They are playing a game together.

    Each of Matt’s friends has a magic number. In the game, Matt selects some (could be zero) of his friends. If the xor (exclusive-or) sum of the selected friends’magic numbers is no less than M , Matt wins.

    Matt wants to know the number of ways to win.
     
    Input
    The first line contains only one integer T , which indicates the number of test cases.

    For each test case, the first line contains two integers N, M (1 ≤ N ≤ 40, 0 ≤ M ≤ 106).

    In the second line, there are N integers ki (0 ≤ ki ≤ 106), indicating the i-th friend’s magic number.
     
    Output
    For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1) and y indicates the number of ways where Matt can win.
     
    Sample Input
    2
    3 2
    1 2 3
    3 3
    1 2 3
     
    Sample Output
    Case #1:
    4 Case #2: 2
    Hint
    In the first sample, Matt can win by selecting: friend with number 1 and friend with number 2. The xor sum is 3. friend with number 1 and friend with number 3. The xor sum is 2. friend with number 2. The xor sum is 2. friend with number 3. The xor sum is 3. Hence, the answer is 4.
     

    题意:题目大意:n个数,从中挑k个,使得这k个数的异或和不小于m,问有多少种挑选方法(0<=k<=n)

    思路:dp[i][j]表示前 i 个数中选择一些使得异或和为j的方法数,转移方程:dp[i][j] = dp[i - 1][j] + dp[i - 1][j ^ a[i]],即等于前i-1个异或和为j的方法数(第i个数不需要进行异或)加上前i-1个异或和为j ^ a[i]的方法数(第i个数需要异或),因为j ^ a[i] ^ a[i] == j ^ (a[i] ^ a[i]) == j ^ 0 = j,最后再累计一下j大于等于m时的方法数,这题内存给的够大,也可以直接采用滚动数组

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<vector>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define ll long long
    int const maxn = (1<<20);
    const int mod = 1e9 + 7;
    int gcd(int a, int b) {
        if (b == 0) return a;  return gcd(b, a % b);
    }
    
    int a[42];
    ll dp[42][maxn];
    int main()
    {
        int t;
        scanf("%d",&t);
        int ca=1;
        while(t--)
        {
            int n,m;
            
            memset(dp,0,sizeof(dp));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            dp[0][0]=1;
            for(int i=1;i<=n;i++)
                for(int j=0;j<maxn;j++)
                    dp[i][j]=dp[i-1][j]+dp[i-1][j^a[i]];   //如果前i-1个数异或值是j就不需要将第i个数进行异或,如果前i-1个数有异或后是j^a[i]的,那么第i个数进行异或,刚好可以得j
            ll ans=0;
            printf("Case #%d: ",ca++);
            for(int i=m;i<maxn;i++)
                ans+=dp[n][i];
            printf("%lld
    ",ans);
        }
        return 0;
    }
     
     
  • 相关阅读:
    Spark数据读取
    05、TypeScript 中的泛型
    04、TypeScript 中的接口
    03、TypeScript 中的类
    02、TypeScript 中的函数
    01、TypeScript 数据类型
    Vue-router 知识点
    什么是跨域?如何解决跨域问题
    工作中积累的问题、知识点总结100题(0-20)
    封装一个 Promise 对象。了解其原理
  • 原文地址:https://www.cnblogs.com/smallhester/p/9513791.html
Copyright © 2011-2022 走看看