bnuoj 24250 Binary Operations (概率DP)

本文介绍了一种使用位DP的方法来解决概率计算问题。通过将数据分解成每一位进行DP,统计到第n位为1的概率。这种方法适用于需要计算特定位上出现1的概率场景。

将数据分成一位一位的进行dp,统计到第n位为1的概率

#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;
typedef long long ll;
const int N = 5 * 1e4 + 10;
ll num[N];
double dpa[N], dpo[N], dpx[N];
int main() {
	int t;
	scanf("%d", &t);
	int CASE = 1;

	while (t--) {
		int n;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) 
			scanf("%lld", num + i);

		double all = ((double)n * (n + 1)) / 2.0;
		double suma, sumo, sumx;
		double ansa, anso, ansx;
		memset(dpa, 0, sizeof(dpa));
		memset(dpo, 0, sizeof(dpo));
		memset(dpx, 0, sizeof(dpx));
		for (int i = 0; i < 31; i++) {
			suma = sumo = sumx = 0;
			for (int j = 1; j <= n; j++) {
				if (num[j] & (1LL << i)) {
					dpa[j] = dpa[j - 1] + 1;
					dpo[j] = j;
					dpx[j] = j - dpx[j - 1];
				}		
				else {
					dpa[j] = 0;
					dpo[j] = dpo[j - 1];	
					dpx[j] = dpx[j - 1];
				}
				suma += dpa[j];
				sumo += dpo[j];
				sumx += dpx[j];
			}	
			ansa += (1LL << i) * suma / all;
			anso += (1LL << i) * sumo / all;
			ansx += (1LL << i) * sumx / all;
		}
		printf("Case #%d: %.6lf %.6lf %.6lf\n", CASE++, ansa, anso , ansx);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值