HDU 5119 Happy Matt Friends(2014北京区域赛现场赛H题 裸背包DP)

虽然是一道还是算简单的DP,甚至不用滚动数组也能AC,数据量不算很大。

对于N个数,每个数只存在两个状态,取 和 不取。

容易得出状态转移方程:

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

dp[i][j] 的意思是,对于数列 中前 i 个数字,使得 XOR 和恰好为 j 的方案数

状态转移方程中的 dp[i - 1][j] 即表示当前这个数字不取, dp[i - 1][j ^ a[i]] 表示当前这个数字要取。

 

这道题还是要好好理解阿!

source code :

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))

using namespace std;

const int INF = 0x3f3f3f3f;

int dp[2][1 << 20];
int a[41];

int main(){
    int i, j, k, T, n, m, numCase = 0;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        for(i = 1; i <= n; ++i) scanf("%d", a + i);
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        for(i = 1; i <= n; ++i){
            for(j = 0; j < (1 << 20); ++j){
                dp[i % 2][j] = dp[(i - 1) % 2][j ^ a[i]] + dp[(i - 1) % 2][j];
            }
        }
        long long ans = 0;
        for(i = m; i < (1 << 20); ++i){
            ans += dp[n % 2][i];
        }
        printf("Case #%d: %I64d\n",++numCase, ans);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/wushuaiyi/p/4143220.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值