标签:style http color 使用 os io for 代码
题目链接:uva 1489 - Math teacher‘s homework
题目大意:给定n,k,以及序列m1,m2,…,mn, 要求找到一个长度为n的序列,满足0<=xi<=mi, 并且x1XORx2XOR…XORxn=k
解题思路:数位dp,在网上看了别人的代码,高大上。。。
假设有二进制数 k : 00001xxxx
mi:0001xxxxx,
那么对于xi即可以满足任意的x1XORx2XOR…XORxi?1XORxi+1XOR…XORxn,根据这一点进行数位dp。
dp[i][j]表示在第i个数,对于当前位是由j个1没有使用的。
特别对于dp[i][1] = dp[i][1] + dp[i-1][0], 因为dp[i-1][0]是没有1可以用的,即使不满足说随便添加数都是可以的,所以不能乘以bits。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 55;
const ll MOD = 1000000003LL;
ll N, K;
ll dp[maxn][maxn], num[maxn];
int main () {
while (scanf("%lld%lld", &N, &K) == 2 && (N + K)) {
ll ans = 0;
for (int i = 1; i <= N; i++)
scanf("%lld", &num[i]);
int bit;
for (bit = 30; bit >= 0; bit--) {
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
ll cnt = 0, bits = (1<<bit);
for (int i = 1; i <= N; i++) {
if (num[i]&bits) {
cnt++;
for (int j = 0; j <= cnt; j++)
dp[i][j] = dp[i-1][j] * (num[i] - bits + 1) % MOD;
dp[i][1] = (dp[i][1] + dp[i-1][0]) % MOD;
for (int j = 2; j <= cnt; j++)
dp[i][j] = (dp[i-1][j-1] * bits + dp[i][j]) % MOD;
num[i] -= bits;
} else {
for (int j = 0; j <= cnt; j++)
dp[i][j] = dp[i-1][j] * (num[i] + 1) % MOD;
}
}
for (int i = 1; i <= cnt; i++)
if ( ((cnt - i)&1) == ((K>>bit)&1) )
ans = (ans + dp[N][i]) % MOD;
if ( (cnt&1) != ((K>>bit)&1) )
break;
}
if (bit == -1)
ans++;
printf("%lld\n", ans);
}
return 0;
}
uva 1489 - Math teacher's homework(数位dp),布布扣,bubuko.com
uva 1489 - Math teacher's homework(数位dp)
标签:style http color 使用 os io for 代码
原文地址:http://blog.csdn.net/keshuai19940722/article/details/38307369