주제 링크 : HDU 5119
문제 설명
매트는 N 친구가 있습니다. 그들은 함께 게임을하고 있습니다.
매트의 친구의 각각은 마법을 가지고 있습니다. 게임에서 매트 (영 수) 그의 친구 중 일부를 선택합니다. 배타적 논리합은 (배타적 OR) 선택한 friends'magic 숫자의 합이 M보다 적은없는 경우, 매트가 승리.
매트는 승리 할 수있는 방법의 수를 알고 싶어한다.
입력
첫 번째 라인은 하나의 정수 포함 \ (T \) 테스트 케이스의 수를 나타낸다.
테스트 케이스를 들어, 첫 번째 행은 두 정수 포함 \ (N, M (1 \ 르 N을 \ 르 40 0 \ 르 M \ 르 10 ^ 6) \) .
두 번째 행에있다 \ (N \) 의 정수 (\ k_i (0 ≤ k_i ≤ 10 ^ 6) \) , 상기 지시 \ (나는 \) 번째의 친구의 매직 넘버.
산출
출력 한 줄 "케이스 #x를 : Y"테스트 케이스를 들어 X는 케이스 번호 (1에서 시작) 및 Y 인 매트 이길 수있는 방법의 수를 나타낸다.
샘플 입력
2
3 2
1 2 3
3 3
1 2 3
샘플 출력
Case #1: 4
Case #2: 2
힌트
Fi를의 첫 번째 샘플에서 매트를 선택하여 이길 수 :
번호 2와 숫자와 친구의 친구는 XOR 합은 3이다.
숫자 3과 1 번과 친구와 친구는 XOR의 합은 2입니다.
숫자 2와 친구는 XOR의 합은 2입니다.
수 (3) 배타적 합 친구는 대답은 4, 따라서 3입니다.
출처
2014ACM / ICPC 아시아 북경 역은 - (북한 부문에 대한 감사 및 인계) 게임을 재현하는 방법
해결책
문제의 의미
을 감안할 때 \ (N- \) 수 \ (K는 [내가] \) 보다 크거나 그 독점와 같은 몇 개의 발생한 \ (m의 \)를 여러 에뮬레이트 찾을 수 있습니다.
생각
DP 압연 배낭 어레이
세트 \ (DP [I] [j는 ] \) 전 나타낸다 \ (I는 \) 번호 및 배타적 OR 위해 \ (J \) 모두 에뮬레이트. 상태 전이 방정식은 \ ([. 1 - I] [J] + DP [I -. 1] DP [I] [J] DP = [J \ XOR \ K [I] \) .
현재의 상태와 이전 상태, 따라서 사람뿐만 롤 배열을 최적화하기 위해 사용될 수있다.
암호
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1 << 20;
ll dp[10][maxn];
ll k[50];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
for(int _ = 1; _ <= T; ++_) {
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; ++i) {
cin >> k[i];
}
for(int i = 1; i <= n; ++i) {
for(int j = 0; j < maxn; ++j) {
dp[i & 1][j] = dp[(i - 1) & 1][j] + dp[(i - 1) & 1][j ^ k[i]];
}
}
ll ans = 0;
for(int i = m; i < maxn; ++i) {
ans += dp[n & 1][i];
}
cout << "Case #" << _ << ": " << ans << endl;
}
return 0;
}