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

min-max容斥:

$$max\{a_i\}=\sum\limits_{S}(-1)^{|s|-1}min\{a_i|a_i \in S\}$$

关于证明,可以把一个数$a$看作是集合$\{1...a\}$,于是max相当于取并集,min相当于取交集,就变成了普通的容斥

然后这道题就可以dp了

然而我一直被卡精度 以下代码大概是对的(

 1 #include<bits/stdc++.h>
 2 #include<tr1/unordered_map>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 #define MP make_pair
 5 #define fi first
 6 #define se second
 7 using namespace std;
 8 typedef long long ll;
 9 typedef unsigned long long ull;
10 typedef long double ld;
11 typedef pair<int,int> pa;
12 const int maxn=55;
13 
14 inline ll rd(){
15     ll x=0;char c=getchar();int neg=1;
16     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
17     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
18     return x*neg;
19 }
20 
21 int N,f[maxn][2][2*maxn*maxn];
22 
23 int main(){
24     //freopen("","r",stdin);
25     for(int T=rd();T;T--){
26         N=rd();
27         ld ans=0;
28         CLR(f,0);f[0][0][0]=1;
29         for(int i=1;i<=N+1;i++){
30             for(int b=0;b<=1;b++){
31                 for(int ii=0;ii<i;ii++){
32                     for(int j=0;j<=ii*(ii+1);j++){
33                         f[i][b][j+(i-ii-1)*(i-ii)]+=f[ii][!b][j];
34                     }
35                 }
36             }
37         }
38         for(int b=0;b<=1;b++){
39             for(int j=0;j<N*(N+1);j++){
40                 ans+=(b?-1:1)*(1.0L/(1-1.0L*j/(N*(N+1))))*f[N+1][b][j];
41             }
42         }
43         printf("%.15Lf\n",ans);
44     }
45     return 0;
46 }

 

posted @ 2019-06-07 16:23  Ressed  阅读(101)  评论(0编辑  收藏