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 }