UESTC 84 DP
2017-02-20 20:43
381 查看
题意
给n个数,可以从这n个数中连续取任意个数进行与、或、异或运算。求与、或、异或运算的期望。题解
设dp[i]为最后一个数字为i,满足条件的数列个数。运算按位进行,求出运算后使该位等于1的数列个数,然后乘以权值,再除以(n+1)*n/2,即可得到期望。对于每种运算,状态转移分两种情况。该位为1:
与运算:dpa[i]=dpa[i-1]+a (a代表该数字前连续为1的数字个数)
或运算:dpo[i]=dpo[i-1]+i(i代表该数字前数字个数)
异或运算:dpx[i]=dpx[i-1]+i-v(v代表该数字前数字进行异或运算,结果为1的情况个数)
该位为0:
与运算:dpa[i]=dpa[i-1]
或运算:dpo[i]=dpo[i-1]+b(i代表该数字前数字进行或运算,结果为1的情况个数)
异或运算:dpx[i]=dpx[i-1]+v(v代表该数字前数字进行异或运算,结果为1的情况个数)
注意事项
dp[i]可能会很大,因此要用long long代码
#include <iostream> #include<cstdio> #include<algorithm> #define MAXN 50010 typedef long long ll; int num[MAXN]; ll dpa[MAXN],dpo[MAXN],dpx[MAXN]; int n; using namespace std; void dp(){ dpa[0]=0,dpo[0]=0,dpx[0]=0; int a=0,b=0,v=0; for(int i=1;i<=n;i++){ if(1&num[i]){ a++; dpa[i]=dpa[i-1]+a; dpo[i]=dpo[i-1]+i; dpx[i]=dpx[i-1]+i-v; b=i; v=i-v; }else{ a=0; dpa[i]=dpa[i-1]; dpo[i]=dpo[i-1]+b; dpx[i]=dpx[i-1]+v; } num[i]=num[i]>>1; } } int main() { int t; scanf("%d",&t); for(int ks=1;ks<=t;ks++){ scanf("%d",&n); int maxnum=0; for(int i=1;i<=n;i++){ scanf("%d",&num[i]); maxnum=max(maxnum,num[i]); } int j=1; double ans1=0,ans2=0,ans3=0; while(maxnum>0){ dp(); ans1+=dpa *j; ans2+=dpo *j; ans3+=dpx *j; j=j<<1; maxnum=maxnum>>1; } double x=(double)n*(n+1)/2; printf("Case #%d: ",ks); printf("%.6f %.6f %.6f\n",ans1/x,ans2/x,ans3/x); } return 0; }
相关文章推荐
- UESTC 1186 Gray code - 简单数位dp
- UESTC-我要长高 DP优化
- UESTC 885 方老师买表 --状压DP
- [dp]uestc oj E - 菲波拉契数制
- UESTC 2015dp专题 j 男神的约会 bfs
- uestc 250 windy数 【数位dp】
- UESTC 426 Food Delivery (区间DP)
- UESTC 1321 柱爷的恋爱 (区间DP)
- uestc1307 windy数 (数位DP)
- UESTC 1271 Search gold (DP)
- UESTC 1218(DP)
- uestc 250 windy数 【数位dp】
- uestc 1307 数位DP
- UESTC 1307 windy数(数位DP)
- 几个基础数位DP(hdu 2089,hdu 3555,uestc 1307 windy 数)
- UESTC 1307 windy数 数位DP
- UESTC - 1357 柱爷与最大区间和(简单dp)
- UESTC 876 爱管闲事 --DP
- UESTC 886 方老师金币堆 --合并石子DP
- UESTC - 1271 Search gold (DP)