Atcoder Grand Contest 020 F - Arcs on a Circle(DP+小技巧)
一道难度 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+小技巧)的更多相关文章
- Atcoder Grand Contest 030 F - Permutation and Minimum(DP)
洛谷题面传送门 & Atcoder 题面传送门 12 天以前做的题了,到现在才补/yun 做了一晚上+一早上终于 AC 了,写篇题解纪念一下 首先考虑如果全是 \(-1\) 怎么处理.由于我 ...
- Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)
题目传送门 典型的 Atcoder 风格的计数 dp. 题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序 ...
- AtCoder Grand Contest 002 F:Leftmost Ball
题目传送门:https://agc002.contest.atcoder.jp/tasks/agc002_f 题目翻译 你有\(n*k\)个球,这些球一共有\(n\)种颜色,每种颜色有\(k\)个,然 ...
- AtCoder Grand Contest 017 F - Zigzag
题目传送门:https://agc017.contest.atcoder.jp/tasks/agc017_f 题目大意: 找出\(m\)个长度为\(n\)的二进制数,定义两个二进制数的大小关系如下:若 ...
- AtCoder Grand Contest 003 F - Fraction of Fractal
题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_f 题目大意: 给定一个\(H×W\)的黑白网格,保证黑格四连通且至少有一个黑格 定义分形如下 ...
- AtCoder Grand Contest 011 F - Train Service Planning
题目传送门:https://agc011.contest.atcoder.jp/tasks/agc011_f 题目大意: 现有一条铁路,铁路分为\(1\sim n\)个区间和\(0\sim n\)个站 ...
- AtCoder Grand Contest 010 F - Tree Game
题目传送门:https://agc010.contest.atcoder.jp/tasks/agc010_f 题目大意: 给定一棵树,每个节点上有\(a_i\)个石子,某个节点上有一个棋子,两人轮流操 ...
- AtCoder Grand Contest 016 F - Games on DAG
题目传送门:https://agc016.contest.atcoder.jp/tasks/agc016_f 题目大意: 给定一个\(N\)点\(M\)边的DAG,\(x_i\)有边连向\(y_i\) ...
- Atcoder Grand Contest 038 F - Two Permutations(集合划分模型+最小割)
洛谷题面传送门 & Atcoder 题面传送门 好久前做的题了--今天偶然想起来要补个题解 首先考虑排列 \(A_i\) 要么等于 \(i\),要么等于 \(P_i\) 这个条件有什么用.我们 ...
随机推荐
- 电脑日常使用bug记录
1.由于电脑太卡了,于是决定关一点服务,一不小心,电脑无线无法使用了.启动无线服务时提示"windows无法启动wlan autoconfig服务错误1068依赖服务" 启动 Ex ...
- 解决Mybatis 报错Invalid bound statement (not found)
解决Mybatis 报错Invalid bound statement (not found) 出现此错误的原因 1.xml文件不存在 2.xml文件和mapper没有映射上 namespace指定映 ...
- 三分钟极速体验:Java版人脸检测
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Coursera Deep Learning笔记 序列模型(一)循环序列模型[RNN GRU LSTM]
参考1 参考2 参考3 1. 为什么选择序列模型 序列模型能够应用在许多领域,例如: 语音识别 音乐发生器 情感分类 DNA序列分析 机器翻译 视频动作识别 命名实体识别 这些序列模型都可以称作使用标 ...
- MySQL 8.0安装 + 配置环境变量 + 连接 cmd
MySQL 安装教程 搜索 MySQL,进入官网,找到 download 点击适用于 window community 版本,点击图中第二个 450.7 M 的安装包进行下载 这里有五个选项,选择第二 ...
- qwt使用细节
在使用QWT进行二维曲线绘制,使用方法如下: class Plot: public QwtPlot { Q_OBJECT -- } 报错:error LNK2001: 无法解析的外部符号"p ...
- Python课程笔记(九)
本次课程主要学习了Excel和JSON格式的一些读写操作.课程代码 一.Excel数据读写操作 1.安装模块 pip install xlrd pip install xlwt 网不好可以采用三方库: ...
- Java并发:Condition接口
Condition 接口与 Lock 配合实现了等待 / 通知模式,这个和 Object 的监视器方法(wait.notify.notifyAll 等方法)一样,都是实现了等待 / 通知模式,但这两者 ...
- Linux下文件的三种时间标记:访问时间、修改时间、状态改动时间 (转载)
在windows下,一个文件有:创建时间.修改时间.访问时间. 而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 两者有此不同,在Linux下没有创建时间的概念,也就 ...
- 最短路spaf及dijkstra模板
spaf的双端队列优化: #include<bits/stdc++.h> #define ll long long const ll maxn=210000; using namespac ...