题解 exp
因为是在补题解所以所有公式都省了
解释一下当时不太能理解的地方
这里这个
由于
所以这里相当于在算加权平均数,其中 是这个权
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 405
#define ll long long
//#define double long double
//#define int long long
int n;
char s[N];
namespace force{
unordered_map<int, double> mp;
double pre;
double dfs(int s) {
// cout<<"s: "<<bitset<5>(s)<<endl;
double ans=0;
if (!s) return 0.0;
if (mp.find(s)!=mp.end()) return mp[s];
for (int k=1; k<=n; ++k) {
// cout<<"k: "<<k<<endl;
double add=0;
int now=k;
while (!(s&(1<<now))) {
++add;
now=(now%n)+1;
}
add+=dfs(s^(1<<now));
// cout<<"add: "<<add<<endl;
ans+=pre*add;
}
return mp[s]=ans;
}
void solve() {
mp.clear();
int tem=0;
for (int i=1; i<=n; ++i) if (s[i]=='.') tem|=1<<i;
pre=1.0/n;
printf("%.9lf\n", dfs(tem));
}
}
namespace task{
int sum[N];
double fac[N], inv[N], F[N][N], G[N][N], P[N][N], ans;
inline double qpow(double a, int b) {double ans=1; for (; b; a=a*a,b>>=1) if (b&1) ans=ans*a; return ans;}
inline double C(int n, int k) {return fac[n]*inv[k]*inv[n-k];}
double g(int l, int r);
double p(int l, int r, int k) {
if (s[r]=='X'||s[k]=='X') return 0;
// if (P[l][r][k]>0) return P[l][r][k];
int lc=sum[k-1]-sum[l-1], rc=sum[r-1]-sum[k];
// return P[l][r][k]=C(lc+rc, lc)*qpow((k-l+1.0)/(r-l+1.0), lc)*g(l, k)*qpow((r-k)/(r-l+1.0), rc)*g(k+1, r)*(k-l+1.0)/(r-l+1.0);
return C(lc+rc, lc)*qpow((k-l+1.0)/(r-l+1.0), lc)*g(l, k)*qpow((r-k)/(r-l+1.0), rc)*g(k+1, r)*(k-l+1.0)/(r-l+1.0);
}
double g(int l, int r) {
if (s[r]=='X') return 0;
if (l==r) return 1;
if (sum[r]-sum[l-1]==1) return 1;
if (G[l][r]>0) return G[l][r];
double ans=0;
for (int k=l; k<r; ++k) ans+=p(l, r, k);
return G[l][r]=ans;
}
double f(int l, int r) {
// cout<<"f: "<<l<<' '<<r<<endl;
if (l==r || s[r]=='X' || sum[r]-sum[l-1]==1) return 0;
if (F[l][r]>0) return F[l][r];
double ans=0;
for (int k=l; k<r; ++k) ans+=p(l, r, k)*(f(l, k)+f(k+1, r)+(k-l)/2.0);
// cout<<"return: "<<ans/g(l, r)<<endl;
return F[l][r]=g(l, r)>0?ans/g(l, r):0;
}
void solve() {
memset(F, 0xc2, sizeof(F));
memset(G, 0xc2, sizeof(G));
memset(P, 0xc2, sizeof(P));
// cout<<double(sizeof(P))/1000/1000<<endl;
fac[0]=fac[1]=1; inv[0]=inv[1]=1; ans=(n-1)/2.0;
for (int i=2; i<=n; ++i) fac[i]=fac[i-1]*i;
for (int i=2; i<=n; ++i) inv[i]=1.0/i;
for (int i=2; i<=n; ++i) inv[i]=inv[i-1]*inv[i];
for (int i=1; i<=n; ++i) s[n+i]=s[i];
for (int i=1; ; ++i)
if (i>n) {puts("0.000000000"); return ;}
else if (s[i]=='.') break;
for (int i=1; i<=2*n; ++i) sum[i]=sum[i-1]+(s[i]=='.');
// cout<<"sum: "; for (int i=1; i<=n*2; ++i) cout<<sum[i]<<' '; cout<<endl;
for (int i=1; i<=n; ++i) ans+=f(i, i+n-1)*g(i, i+n-1);
printf("%.9lf\n", ans);
}
}
signed main()
{
int T;
scanf("%d", &T);
while (T--) {
scanf("%s", s+1);
n=strlen(s+1);
// force::solve();
task::solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术