Atcoder 题面传送门 & 洛谷题面传送门

一道难度 unavailable 的 AGC F 哦

首先此题最棘手的地方显然在于此题的坐标可以为任意实数,无法放入 DP 的状态,也无法直接计算概率。我们考虑是否能将实数坐标转化为我们熟知的整数坐标。这里有一个套路,注意到每条弧的长度都是整数这个条件,考虑两个坐标 \(A,B\),显然以 \(A\) 开始的长度为 \(l\) 的弧能覆盖到 \(B\) 当且仅当 \(\lfloor B\rfloor-\lfloor A\rfloor<l\),或者 \(\lfloor B\rfloor-\lfloor A\rfloor=l\) 且 \((B-\lfloor B\rfloor)<(A-\lfloor A\rfloor)\)。这就告诉我们,坐标的小数部分具体是什么并不重要,我们只关心它们的相对大小。又因为小数部分为取值范围为 \([0,1)\) 的连续性变量,因此出现两点小数部分相同的概率可以视作 \(0\),因此我们暴力枚举这 \(n\) 条线段小数部分的相对大小——共有 \(n!\) 种可能的情况,它们是等可能的(yyq 既视感),计算出它们覆盖整个圆周的概率后除以 \(n!\) 即可。

接下来考虑给定这 \(n\) 条线段小数部分的相对大小后怎样计算概率,首先我们固定住一条线段的位置,这样即可实现断环成链,其次由于我们已经知道了它们的相对大小了,所以最多只可能有 \(nc\) 个起点位置,故可将 \(c\) 个坐标拆成 \(nc\) 个并将线段覆盖转化为点覆盖——这个异常容易理解。我们强制要求小数部分相对大小排名为 \(k\) 的线段只能在 \(tn+k(t\in\mathbb{Z})\) 的位置作为起始位置。这样就可以 \(dp\) 了,设 \(dp_{i,j,k}\) 表示现在覆盖了起点坐标 \(\leq i\) 的线段,当前覆盖到的右端点的最大值为 \(j\),当前使用的线段集合为 \(k\)(这个状态设计感觉有点像此题),转移就分 \(i\) 处不放线段和放线段两种情况转移即可,显然如果 \(i\) 处放线段,那放置的线段是唯一的(\(i\bmod n\)),因此总复杂度 \(n!\times 2^n\times n\times c\),由于此题 \(n\) 数据范围极小,可通过此题。

最后值得一提的是不少题解都没有提到一点,就是为什么一定要强制令长度最大的线段的起点为圆周的起始位置,这里稍微讲下,因为假设我们用一个长度较小的线段作为圆周的起始位置,根据我们的 DP 过程可知对于线段超过断成的链的部分我们会直接忽略,但有可能会出现长度较大的线段从链的末尾开始覆盖,由于这是一个圆周,因此多出的部分又绕回链的开头,补上链开头线段覆盖的空隙的情况,这种情况是不会被我们纳入总方案的,不过 in fact 这种方案也是合法的。而使用长度最大的线段作为开头就恰好避免的这种情况,因此需要强制令长度最大的线段的起点为圆周的起始位置。

似乎 WC2021 的时候 lyx 神仙给出了一个更优秀的解法,要什么高级插值技巧什么的,not for me,thx

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=6;
const int MAXC=50;
int n,l[MAXN+2],c,p[MAXN+2];
ll dp[MAXN*MAXC+5][(1<<MAXN)+5];
int main(){
scanf("%d%d",&n,&c);ll ret=0;
for(int i=0;i<n;i++) scanf("%d",&l[i]),p[i]=i;
sort(l,l+n);reverse(l,l+n);
do {
memset(dp,0,sizeof(dp));dp[l[p[0]]*n][1]=1;
for(int i=1;i<n*c;i++) for(int j=i;j<=n*c;j++){
int t=i%n;
for(int k=0;k<(1<<n);k++) if(~k>>t&1)
dp[min(n*c,max(j,i+l[p[t]]*n))][k|(1<<t)]+=dp[j][k];
} ret+=dp[n*c][(1<<n)-1];
} while(next_permutation(p+1,p+n));
double ans=ret;//printf("%lld\n",ret);
for(int i=1;i<=n-1;i++) ans=1.*ans/i;
for(int i=2;i<=n;i++) ans=1.*ans/c;
printf("%.17lf\n",ans);
return 0;
}

Atcoder Grand Contest 020 F - Arcs on a Circle(DP+小技巧)的更多相关文章

  1. Atcoder Grand Contest 030 F - Permutation and Minimum(DP)

    洛谷题面传送门 & Atcoder 题面传送门 12 天以前做的题了,到现在才补/yun 做了一晚上+一早上终于 AC 了,写篇题解纪念一下 首先考虑如果全是 \(-1\)​ 怎么处理.由于我 ...

  2. Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)

    题目传送门 典型的 Atcoder 风格的计数 dp. 题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序 ...

  3. AtCoder Grand Contest 002 F:Leftmost Ball

    题目传送门:https://agc002.contest.atcoder.jp/tasks/agc002_f 题目翻译 你有\(n*k\)个球,这些球一共有\(n\)种颜色,每种颜色有\(k\)个,然 ...

  4. AtCoder Grand Contest 017 F - Zigzag

    题目传送门:https://agc017.contest.atcoder.jp/tasks/agc017_f 题目大意: 找出\(m\)个长度为\(n\)的二进制数,定义两个二进制数的大小关系如下:若 ...

  5. AtCoder Grand Contest 003 F - Fraction of Fractal

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_f 题目大意: 给定一个\(H×W\)的黑白网格,保证黑格四连通且至少有一个黑格 定义分形如下 ...

  6. AtCoder Grand Contest 011 F - Train Service Planning

    题目传送门:https://agc011.contest.atcoder.jp/tasks/agc011_f 题目大意: 现有一条铁路,铁路分为\(1\sim n\)个区间和\(0\sim n\)个站 ...

  7. AtCoder Grand Contest 010 F - Tree Game

    题目传送门:https://agc010.contest.atcoder.jp/tasks/agc010_f 题目大意: 给定一棵树,每个节点上有\(a_i\)个石子,某个节点上有一个棋子,两人轮流操 ...

  8. AtCoder Grand Contest 016 F - Games on DAG

    题目传送门:https://agc016.contest.atcoder.jp/tasks/agc016_f 题目大意: 给定一个\(N\)点\(M\)边的DAG,\(x_i\)有边连向\(y_i\) ...

  9. Atcoder Grand Contest 038 F - Two Permutations(集合划分模型+最小割)

    洛谷题面传送门 & Atcoder 题面传送门 好久前做的题了--今天偶然想起来要补个题解 首先考虑排列 \(A_i\) 要么等于 \(i\),要么等于 \(P_i\) 这个条件有什么用.我们 ...

随机推荐

  1. 【数据结构与算法Python版学习笔记】图——基本概念及相关术语

    概念 图Graph是比树更为一般的结构, 也是由节点和边构成 实际上树是一种具有特殊性质的图 图可以用来表示现实世界中很多有意思的事物,包括道路系统.城市之间的航班.互联网的连接,甚至是计算机专业的一 ...

  2. Sequence Model-week1编程题1(一步步实现RNN与LSTM)

    一步步搭建循环神经网络 将在numpy中实现一个循环神经网络 Recurrent Neural Networks (RNN) are very effective for Natural Langua ...

  3. 实用小工具:screen

    实用小工具:screen 首先,吹爆screen screen,实现了不间断的会话服务,通过SSH连接至远程服务器,当使用了screen开启的会话,不会因为你断开SSH而中断在远程服务器上运行的命令. ...

  4. Redis核心原理与实践--Redis启动过程源码分析

    Redis服务器负责接收处理用户请求,为用户提供服务. Redis服务器的启动命令格式如下: redis-server [ configfile ] [ options ] configfile参数指 ...

  5. Allegro如何测量距离,测距工具的使用

    http://www.allegro-skill.com/thread-2480-1-1.html

  6. advanced base-scripting guide in chinese(高级Bash脚本编程指南-10)

    <高级Bash脚本编程指南>Revision 10中文版 github上链接地址: https://github.com/LinuxStory/Advanced-Bash-Scriptin ...

  7. Ubuntu Python2 和 Python3 共存 切换

    例如 你写了代码 创建一个文件 在终端 vim test.py 然后写入代码 print "hello world" 接着运行代码 python test.py 会输出 hello ...

  8. Swift-技巧(一)缩放并填充图片

    摘要 直接操作图片来实现它的缩放或者填充多余空间,首选 UIGraphicsBeginImageContext 函数来实现,它就相当于一个画布,你甚至可以用它来涂鸦. 最近有一个需求,就是将图片先等比 ...

  9. 线程私有数据TSD——一键多值技术,线程同步中的互斥锁和条件变量

    一:线程私有数据: 线程是轻量级进程,进程在fork()之后,子进程不继承父进程的锁和警告,别的基本上都会继承,而vfork()与fork()不同的地方在于vfork()之后的进程会共享父进程的地址空 ...

  10. TestNG 参数化应用

    一.第一种参数化方式(testng.xml配置参数) 1.新建ParameterDemo04类 2.拷贝类的路径 3.testng.xml配置类地址及参数 <?xml version=" ...