专栏文章
AGC020F Arcs on a Circle 题解
AT_agc020_f题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minme0hj
- 此快照首次捕获于
- 2025/12/02 04:46 3 个月前
- 此快照最后确认于
- 2025/12/02 04:46 3 个月前
将所有线段从短到长排序,考虑断环为链,以第 条线段即最长的线段的左端点作为起点,将问题转化为:最长的线段的左端点位于位置 ,其余线段的左端点在 上随机,求 都被覆盖的概率。其中,以最长的线段的左端点作为起点是为了防止存在另一条更长的线段 覆盖了 和 ,对 和 均造成贡献的情况出现。
虽然每条线段的左端点都是在实数范围内随机的,但我们其实只关心小数部分的相对大小关系,且可以认为小数部分两两不同,因此我们可以考虑直接枚举 的排列 表示前 条线段左端点小数部分的相对大小关系。于是我们现在得到了 个整数坐标 ,第 条线段的左端点只能放在 的坐标 上,我们需要求出 都被覆盖的概率。
考虑 dp:设 表示,当前考虑到坐标 ,前 个坐标都被覆盖了,当前使用了的线段的集合为 的方案数。设 ,转移时选择使用或不使用第 条线段即可。由于总方案数为 ,所以此时覆盖 的概率等于 。又由于每种小数部分的相对大小关系的出现概率相等,所以答案即为每个 所对应的 的平均数。
直接计算即可。时间复杂度 。
Cconst int N=7,C=51;
int n,c,V,a[N],p[N],rk[N];
ll ans,dp[N*C][N*C][1<<N],cnt;
void solve(){
cin>>n>>c,V=1<<(n-1);
for(int i=1;i<=n;i++) cin>>a[i],p[i]=i;
sort(a+1,a+n+1);
while(1){
memset(dp,0,sizeof dp);
dp[0][a[n]*n][0]=1,cnt++;
for(int i=1;i<n;i++) rk[p[i]]=i;
for(int i=0;i<n*c;i++){
for(int j=i;j<=n*c;j++){
for(int s=0;s<V;s++){
int k=rk[i%n];
dp[i+1][j][s]+=dp[i][j][s];
if(k!=0&&(!(s&(1<<(k-1))))) dp[i+1][min(max(j,i+a[k]*n),c*n)][s|(1<<(k-1))]+=dp[i][j][s];
}
}
}
ans+=dp[n*c][n*c][V-1];
if(!next_permutation(p+1,p+n)) break;
}
printf("%.18lf",ans*1.0/cnt/pow(c,n-1));
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...