hdu4624 Endless Spin(min-max容斥,dp)

Problem Description
I spin it again and again,and throw it away finally.
So now I have a row of n ball,named from 1 to n,each ball is white initially.
At each step I randomly chose a interval [l, r] and paint all ball in this interval to black.
It means every 在这里插入图片描述interval have a equal chance of being chosen.
And I’ll stop if all ball are black.What is the expected steps before I stop?

Input
The first line contains integer T(1<=T<=50). Denoting the number of the test cases.
Then T lines follows, each line contains an integer n (1<=n<=50).

Output
For each test cases,print the answer in a line.
Print the answer rounded to 15 decimal places.

Sample Input
3
1
2
3

Sample Output
1.000000000000000
2.000000000000000
2.900000000000000

Hint

不建议使用long double

Author
WJMZBMR

Source
2013 Multi-University Training Contest 3

Recommend
zhuyuanchen520 | We have carefully selected several similar problems for you: 6460 6459 6458 6457 6456


题目大意:
N N N个球排成一排,初始为白色,每次随意一个区间 [ l , r ] [l,r] [l,r]染黑,问期望染多少次能把所有球染黑
N &lt; = 50 N&lt;=50 N<=50


m i n − m a x min-max minmax容斥
显然可以得到式子
a n s = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − 1 ∗ E ( T ) ans=\sum_{T\subseteq S}(-1)^{|T|-1}*E(T) ans=TS(1)T1E(T)
E ( T ) E(T) E(T)表示期望染多少次能染到集合 T T T中的元素

现在问题就是怎么求 E ( T ) E(T) E(T),并快速统计答案

易得 E ( T ) = 总 区 间 数 合 法 区 间 数 = 总 区 间 数 总 区 间 数 − 不 合 法 区 间 数 E(T)=\frac{总区间数}{合法区间数}=\frac{总区间数}{总区间数-不合法区间数} E(T)==

假设集合 T T T中的球为红球,其他为绿球,我们把每一段的绿球的个数构成一个序列 a i ( i ∈ [ 1 , k ] ) {a_i}(i\in[1,k]) ai(i[1,k])
则不合法区间数 = ∑ i = 1 k a i ∗ ( a i + 1 ) 2 =\sum_{i=1}^k \frac{a_i*(a_i+1)}{2} =i=1k2ai(ai+1)


a n s = ∑ T ⊆ S ( − 1 ) ∣ T ∣ − 1 ∗ n ∗ ( n + 1 ) 2 n ∗ ( n + 1 ) 2 − ∑ i = 1 k a i ∗ ( a i + 1 ) 2 ans=\sum_{T\subseteq S}(-1)^{|T|-1}*\frac{\frac{n*(n+1)}{2}}{\frac{n*(n+1)}{2}-\sum_{i=1}^k\frac{a_i*(a_i+1)}{2}} ans=TS(1)T12n(n+1)i=1k2ai(ai+1)2n(n+1)

f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]表示前 i i i个球,第 i i i个球为红球,红球个数的奇偶性为 j ( 0 / 1 ) j(0/1) j(0/1),不合区间数为 k k k的方案数

转移的时候枚举下一段绿球即可

这题直接小数输出精度不够,得用高精度
可以把所有正的和负的先加起来(能好写很多)

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back 
#define pc putchar
#define mp make_pair
#define file(k) memset(k,0,sizeof(k))
#define ll long long
int rd()
{
    int sum = 0;char c = getchar();bool flag = true;
    while(c < '0' || c > '9') {if(c == '-') flag = false;c = getchar();}
    while(c >= '0' && c <= '9') sum = sum * 10 + c - 48,c = getchar();
    if(flag) return sum;
    else return -sum;
}
const int N = 51;
ll f[52][2][2501];
struct point{ll zs;int xs[110];}ans,tmp;
void change(point &a,ll x,int y)
{
	x -= x/y*y;
	rep(i,1,100) x *= 10,a.xs[i] += x/y,x -= x/y*y;
	repp(i,100,1) a.xs[i-1] += a.xs[i]/10,a.xs[i] %= 10;
	a.zs += a.xs[0];a.xs[0] = 0;
} 
void del()
{
	ans.zs -= tmp.zs;
	repp(i,100,1) ans.xs[i] -= tmp.xs[i],
	              ans.xs[i-1] -= ans.xs[i] < 0 ? 1 : 0,
				  ans.xs[i] = (ans.xs[i] + 10) % 10;
	ans.zs += ans.xs[0];ans.xs[0] = 0; 
}
int main() 
{
    f[0][0][0] = 1;
    rep(i,0,N-1) rep(j,0,2500) rep(fl,0,1)
        if(f[i][fl][j]) rep(k,i+1,N) f[k][fl^1][j+(k-i-1)*(k-i)/2] += f[i][fl][j];
    int T = rd(),n,x;
    while(T--)
    {
    	ans.zs = 0;rep(i,0,100) ans.xs[i] = 0;
    	tmp.zs = 0;rep(i,0,100) tmp.xs[i] = 0;
        n = rd();x = n*(n+1)/2;
        rep(i,0,x-1)
        {
            ans.zs += f[n+1][0][i]*x/(x-i);
            change(ans,f[n+1][0][i]*x,x-i);
			tmp.zs += f[n+1][1][i]*x/(x-i);
            change(tmp,f[n+1][1][i]*x,x-i);
        }
        del();
        ans.xs[15] += ans.xs[16] >= 5 ? 1 : 0;
        repp(i,15,1) ans.xs[i-1] += ans.xs[i] / 10,ans.xs[i] %= 10;
        ans.zs += ans.xs[0];
		printf("%lld.",ans.zs);
        rep(i,1,15) printf("%d",ans.xs[i]);printf("\n");
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值