首页 > 其他分享 >[AGC020F] Arcs on a Circle 题解

[AGC020F] Arcs on a Circle 题解

时间:2023-10-19 09:59:40浏览次数:38  
标签:Arcs 题解 线段 times 枚举 Circle AGC020F DP

Arcs on a Circle

首先,一个非常自然的想法是尝试断环成链。怎么断呢?我们发现,选择最长线段的起点处截断是个非常好的选择,因为不可能有一个线段完全覆盖它。这之后,一个紧接着的想法就是 DP。

假如把描述中的全部“实点”改成“整点”的话,那么这题是比较 trivial 的,可以通过随便状压就出来了。

但是现在是实点。怎么办?

DP 状态里必然涉及到记录当前所有线段最远覆盖的位置,但这是个实数,不好记录。

这时候,一个不知道咋想出来的主意便产生了——我们考虑比较两个实数时的步骤,肯定是先比较整数,再比较小数。而因为所有线段长度都是整数,整数部分的大小关系是容易比较的,而小数部分可以选择离散化。具体而言,我们枚举它们小数部分的大小关系构成一个排列,然后将整个长度为 \(c\) 的环变作 \(n\times c\) 个点表示大小关系。我们枚举的排列的实际意义是,限制第一条线段的起始位置只能是 \(1,n+1,2n+1,\dots,(c-1) \times n+1\) 这些位置,再限制第二条线段的位置只能是 \(2,n+2,2n+2,\dots,(c-1) \times n+2\) 这样,大小关系确定,就可以 DP 了,只需要记得枚举完全排列后除以排列数即可。

时间复杂度 \(n!\times 2^n\times(nc)^2\)。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=310;
int n,c,a[6],p[6];
double f[N][1<<5][N<<1],res;
int main(){
    scanf("%d%d",&n,&c);
    for(int i=0;i<n;i++) scanf("%d",&a[i]),p[i]=i;
    sort(a,a+n);
    do{
        f[0][0][a[n-1]*n]=1;
        for(int i=0;i<c*n;i++){
			for(int j=0;j<(1<<(n-1));j++){
				for(int k=i;k<2*c*n;k++){
					f[i+1][j][k]+=f[i][j][k];
					if(i%n&&!(j&(1<<p[i%n-1]))){
						f[i+1][j|(1<<p[i%n-1])][max(k,i+a[p[i%n-1]]*n)]+=f[i][j][k]/c;
					}
					f[i][j][k]=0;
				}
			}
		}
        for(int i=c*n;i<2*c*n;i++){
			res+=f[c*n][(1<<(n-1))-1][i];
			f[c*n][(1<<(n-1))-1][i]=0;
		}
    }while(next_permutation(p,p+n-1));
    for(int i=1;i<n;i++) res/=i;
    printf("%.11lf\n",res);
    return 0;
}

标签:Arcs,题解,线段,times,枚举,Circle,AGC020F,DP
From: https://www.cnblogs.com/xuantianhao/p/17773992.html

相关文章

  • 洛谷 P4749 [CERC2017] Kitchen Knobs 题解
    KitchenKnobs首先,一个trivial的想法是,因为每个旋钮如果上面的数字并非全部相同则其必有唯一最优位置,故直接扔掉那些全部相同的旋钮,对于剩余的求出其最优位置。明显此位置是一\(0\sim6\)的数。因为是区间同时旋转,所以转成数之后就是区间加同一个数。一个经典套路是差分。这......
  • [ABC207F] Tree Patrolling 题解
    [ABC207F]TreePatrolling弱智DP题,设\(f(i,j,0/1/2)\)表示在点\(i\),子树中有\(j\)个点被覆盖,且\(i\)点自身状态是未被覆盖/被自身覆盖/被某个儿子覆盖,然后树上背包更新就行了。代码:#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintmo......
  • CF1542E2 Abnormal Permutation Pairs (hard version) 题解
    AbnormalPermutationPairs(hardversion)两个限制:字典序小、逆序对大,一个显然的想法就是确保一对关系,统计另一对关系。确保哪一对呢?我们想了想,决定确保字典序小,因为字典序是可以贪心的。具体而言,我们考虑两个排列自第\(i\)位开始出现了不同。这样子,我们便将两个排列各自划......
  • AT_tdpc_tree 木 题解
    木弱智DP题,直接设\(f_i\)表示\(i\)子树内染色的方案数,然后每次合并一个点与它的儿子即可(具体而言,因为儿子间独立,所以方案数就是二项式系数)。需要注意的是因为第一条边可以在任意位置,所以要以每个点为根各DP一次。但是这样每条边会被算两次,所以乘以2的逆元即可。时间......
  • [ARC072E] Alice in linear land 题解
    [ARC072E]Aliceinlinearland首先,一个trivial的想法是记\(f_i\)表示第\(i\)步前离终点的距离,于是\(f_i=\min\Big(f_{j-1},|f_{j-1}-d_i|\Big)\)。然后,我们设\(f_i'\)表示在修改第\(i\)步后,此时离终点的距离。明显,\(f_i'\)可以为任意不大于\(f_i\)的值,因为此时......
  • CF568E Longest Increasing Subsequence 题解
    LongestIncreasingSubsequenceLIS问题有两种主流\(O(n\logn)\)解法,最常见的树状数组法,以及不那么常见的二分法。然后考虑本题,发现一个神奇的思路就是求出LIS后倒序复原出数组。进一步思考后发现,因为本题是LIS(LongestIncreasingSubsequence)而非LNDS(LongestNon-Decr......
  • [AGC046D] Secret Passage 题解
    SecretPassage稍微观察一下就能发现,任一时刻,我们剩下的东西必然是一段定死了的后缀,加上一些可以任意塞位置的0与1。考虑任意一个由上述时刻生成的串,就会发现它与该后缀的最长公共子序列长度即为后缀长度,且还剩余一些0与1。于是考虑模拟最长公共子序列的过程。设\(g_{i,j......
  • Atcoder Beginner Contest 324 G Generate Arrays 题解-Treap
    为了更好的阅读体验,请点击这里题目链接套上平衡树板子就能做的很快的题,然后因为是指针存树,因此交换只需要把序列大小较小的挨个拿出来插到相应的地方即可。复杂度\(O(N\log^2N)\)。但是一定要记住不可以直接使用std::swap交换包含带有指针的类的实例(如代码中的Treap类)!......
  • 精选题解汇总
    Part1比赛题解CF1873CF1203CF1234CF1249Part2难题题解P1124P6346P2198P7974P4814......
  • P1124 题解
    题目大意一个长度为\(n\)的字符串\(S\),进行以下操作。假设\(s\)为acbdef,每一次将首字母移至末尾,得到\(6\)个字符串:acbdefcbdefabdefacdefacbefacbdfacbde将每个字符串的首字母排序:acbdefbdefaccbdefadefacbefacbdfacbde每个字符串的末尾连在一起为fcab......