hdu 5119 (类似于划分数的状态定义) (DP中的计数问题)

题目描述:求n个数中异或值大于m的方案数有多少个?

设状态f[i][j]代表前i个数异或值为j的方案数有f[i][j]种,那么对于j来说要么选第i个数与前面的i-1个数中的某些数构成j,f[i-1][j^a[i]]],要么不选第i个数,直接由前面的i-1个数构成j,f[i-1][j];  f[i][j]=f[i-1][j^a[i]] + f[i-1][j] ; 注意到j的取值范围为10^6约等于2^(20),所以n个数亦或的最大值最多为20个1。

亦或的特性 : 任何数与0相亦或不变 ,任何数与本身相亦或为0

设初值f[0][0]=1;

之前用背包那种滚动数组来写,但是会发现d[i][j]= d[i-1][j] + d[i-1][j-V[i]]; 背包方程中不选的话j-V[i]<=j 所以j从大到小遍历,这一行的值只与上一行的值有关,

然而这道题j^a[i]可能大于j,所以这一行的值不能保证只与上一行的值有关。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstring>
#include <algorithm>
#define SIZE 50
#define LL long long
using namespace std;

LL a[50];
LL ans[50][1148576];
void init()
{
    memset(ans,0,sizeof(ans));
}
int main()
{
    //freopen("test.txt","r",stdin);
    int t;
    scanf("%d",&t);
    int cas = 1;
    while(t --)
    {
        LL n,m;
        scanf("%I64d%I64d",&n,&m);
        init();
        for(int i = 1 ; i <= n ; i ++)
        {
            scanf("%I64d",&a[i]);
            //ans[a[i]] = 1;
        }
        LL all=pow(2,n);
        ans[0][0]=1;
        for(int i =  1; i <= n ; i ++)
        {
            for(int j = 0;j<1048576;j++)
                ans[i][j] = ans[i-1][j^a[i]]+ans[i-1][j];

        }
        LL answer=0;
        for(int j=0;j<m;j++)
            answer+=ans[n][j];
        printf("Case #%d: %I64d\n",cas ++,all-answer);
    }
    return 0;
}
时间: 2024-11-09 05:27:48

hdu 5119 (类似于划分数的状态定义) (DP中的计数问题)的相关文章

HDU 5119 Happy Matt Friends ——(背包DP)

题意:有最多40个数字,取任意个数字他们的异或和>=k则是可行的方案,问有多少种可行的方案. 分析:dp[now][j]表示当前这个值的种类数,那么转移方程为dp[now][j] = dp[pre][j] + dp[pre][j^a[i]].因为a^b=c的话,c^b=a,所以j^a[i]就可以得到通过异或a[i]转移到j的那个状态了.然后可以用滚动数组压缩一下. 代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #inc

Hdu 4336 Card Collector (状态概率DP|容斥原理)

详细的题目大意与解析大家参考一下kuangbin的文章. kuangbin链接 这边说一下自己对于kuangbin代码以及容斥原理位元素枚举的理解与解释,希望对大家有所帮助. 状态DP AC代码:状态压缩的思想我就不赘述了,我也只是略懂,这边仅仅分析一下状态方程 由于量比较多,我这边有的便用文字代替,有利于描述. dp[i]表示i状态达到满状态(即收集满n个物品,以下称满状态)所需要的期望. 那么i状态当中收集了x的物品,剩余n-x个物品没有收集 那么dp[i]=p*dp[i]+p2*dp[i2

HDU 1074 Doing Homework (状态压缩DP)

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3595    Accepted Submission(s): 1424 Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lo

HDU 1074 Doing Homework ——(状态压缩DP)

考虑到n只有15,那么状压DP即可. 题目要求说输出字典序最小的答案的顺序,又考虑到题目给出的字符串本身字典序是递增的,那么枚举i的时候倒着来即可.因为在同样完成的情况下,后选字典序大的,小的字典序就会在前面,那么整体的字典序就会更小.代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <string> 5 #include <iostre

位运算在状态压缩DP中的应用

一.判断一个数字X的i位是不是1 方法:  if((1 << (i-1)) & x > 0) 原理: 1左移(i-1)位,相当于制造了一个就i位上是1其他位都是0的一个二进制数.将这个数与X进行“与”运算,如果大于0,则代表第i位是1:否则是0 例子: x = 13 (1101)2 i = 3 ∴ 1 << (i-1) = 1 << 2 = 1002 = 01002 (补上0) ∴ (1 << (i-1)) & x = 01002 &a

2015年沈阳网赛 Jesus Is Here(DP中的计数问题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5459 题目描述:给定一个递推得来的字符串,问字符串中不同cff之间的距离之和, 递推规则: s1=c; s2=ff sn=s[n-2]s[n-1]; 可以观察到任意一个c都被两个ff包含,所以相当于求任意两个c之间的距离之和. 设s[n-2]为p1,p2,p3,,,,p[x],s[n-1]为q1,q2,q3,,,,q[y]; X和y分别为字符串中c的个数:设cnt_c[i]为第i个字符串中c的个数,

POJ 3254 Corn Fields(状态压缩DP)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm

状态压缩dp入门 第一题 POJ 3254 Corn Fields

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6460   Accepted: 3436 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm

hdu6006 Engineer Assignment 状态dp 定义dp[i][s]表示前i个工程状态为s可以执行的最大工程数。s表示前i个工人选走了s状态的工程师。

/** 题目:hdu6006 Engineer Assignment 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6006 题意:已知n个工程,每个需要某些领域的专家.有m个工程师,每个人擅长一些领域. 一个工程师只能参加一个工程.一个工程可以多个工程师参加. 如果参加某个工程的工程师他们擅长的领域覆盖了该工程需要的领域.那么该工程可以执行. 问最多可以执行多少个工程. 思路: 定义dp[i][s]表示前i个工程状态为s可以执行的最大工程数.s表示前