標籤:style blog io ar color os sp for on
雖然是一道還是算簡單的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;}
HDU 5119 Happy Matt Friends(2014北京地區賽現場賽H題 裸背包DP)