首页 > 其他分享 >Atcoder Regular Contest 118 E - Avoid Permutations(容斥+DP)

Atcoder Regular Contest 118 E - Avoid Permutations(容斥+DP)

时间:2023-04-19 17:48:06浏览次数:35  
标签:Atcoder 205 Contest int text Avoid 钦定 DP MOD

挺套路的 DP。

第一步是显然的:转换贡献体,DP 一条从 \((0,0)\) 到 \((n+1,n+1)\) 的路径,然后计算有多少个排列满足这条路径不经过任何一个 \((i,p_i)\)。

正着统计肯定不好求,考虑容斥。即我们钦定一些路径上的点,满足这些点必须对应某个 \((i,p_i)\),然后计算有多少个 \(p\) 符合这个条件,乘以 \((-1)^{\text{钦定的点的个数}}\) 统计入答案。显然如果你钦定的点与已经确定的点的横、纵坐标分别两两不同,那么符合条件的 \(p\) 的个数就是 \((\text{总的 -1 的个数}-\text{你钦定的点的个数})!\)。并且由于我们的路径只能向右或向上,因此判断一个新加入的点的横纵坐标是否与已有的点相同,就只用看当前行和当前列是否有点被钦定。

这样思路就出来了:\(dp_{x,y,k,a,b}\) 表示当前在 \((x,y)\),钦定了 \(k\) 个点,当前行是否有点被钦定的状态为 \(a\),当前列是否有点被钦定的状态为 \(b\)。转移是 simple 的。时间复杂度 \(O(n^3)\)。

#include<bits/stdc++.h>
using namespace std;
const int MOD=998244353;
int n,a[205],dp[205][205][205][2][2],m,fac[205],res;
bool v[205][205],R[205],C[205];
void add(int &x,int v){((x+=v)>=MOD)&&(x-=MOD);}
void sub(int &x,int v){((x-=v)<0)&&(x+=MOD);}
int main(){
	scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);m=n;
	for(int i=1;i<=n;i++)if(~a[i])v[i][a[i]]=R[i]=C[a[i]]=1,m--;
	for(int i=(fac[0]=1);i<=n;i++)fac[i]=1ll*fac[i-1]*i%MOD;
	dp[0][0][0][1][1]=1;
	for(int i=0;i<=n+1;i++)for(int j=0;j<=n+1;j++)for(int k=0;k<=m;k++)
		for(int a=0;a<2;a++)for(int b=0;b<2;b++)if(dp[i][j][k][a][b]){
			int V=dp[i][j][k][a][b];
			if(i<n+1&&!v[i+1][j])add(dp[i+1][j][k][R[i+1]][b],V);
			if(j<n+1&&!v[i][j+1])add(dp[i][j+1][k][a][C[j+1]],V);
			if(!a&&!b&&i<n+1&&!v[i+1][j])sub(dp[i+1][j][k+1][R[i+1]][1],V);
			if(!a&&!b&&j<n+1&&!v[i][j+1])sub(dp[i][j+1][k+1][1][C[j+1]],V);
		}
	for(int k=0;k<=m;k++)res=(res+1ll*fac[m-k]*dp[n+1][n+1][k][0][0])%MOD;
	printf("%d\n",res);
}

标签:Atcoder,205,Contest,int,text,Avoid,钦定,DP,MOD
From: https://www.cnblogs.com/tzcwk/p/arc118E.html

相关文章

  • Contest 23-04-18
    #D.糖果镇思路\(m=3\)时整个路径有两个拐点,分别是\(m=1\tom=2,m=2\tom=3\)设拐点\(1\)在第\(i\)列,拐点\(2\)在第\(j\)列,则路径上的数字总和为\((front[1][i])+(front[2][j]-front[2][i-1])+(back[j])\)(\(front[i][j]\)表示第i行\(1\toj\)的前缀和,\(back[j]\)表......
  • AtCoder Regular Contest 109 E 1D Reversi Builder
    洛谷传送门AtCoder传送门考虑固定\(s\)和每个格子的颜色,最终有多少个石子被染黑。结论:任何时刻只有不多于两个极大同色连通块。证明:设\([x,y]\)为当前的黑连通块,\([y+1,z]\)为白连通块。如果下一次染\(x-1\),若\(x-1\)为白,则\([x-1,z]\)都被染为白;否则\(x-1\)被......
  • AtCoder Regular Contest 109 D L
    洛谷传送门AtCoder传送门这种题根本做不出来……考虑一个L形怎么方便地表示出来。可以发现对于组成L形的三个点\((x_1,y_1),(x_2,y_2),(x_3,y_3)\),只要知道\(x=x_1+x_2+x_3\)和\(y=y_1+y_2+y_3\),就能确定三个坐标。证明是设折点坐标为\((p,q)\),则其余两......
  • AtCoder Regular Contest 106 F Figures
    洛谷传送门AtCoder传送门晚自习的时候胡出来的做法(((首先你会发现题目等价于求\(\sum\limits_{(\sum\limits_{i=1}^na_i)=2(n-1)\land\foralli\in[1,n],1\lea_i\led_i}\prod\limits_{i=1}^n\dfrac{d_i!}{(d_i-a_i)!}\)。翻译一下就是枚举每个点的度数\(a_i\)......
  • ABC297F AtCoder Beginner Contest 297 F - Minimum Bounding Box 2
    https://atcoder.jp/contests/abc297/tasks/abc297_f在\(n\timesm\)的棋盘上放置\(k\)个棋子,记矩形A为能覆盖所有\(k\)个棋子的最小的矩形,求A的面积的期望将问题反过来考虑,枚举每种矩形有多少种放置棋子的方案,对于一个\(n\timesm\)的矩形,我们可以用容斥的方法......
  • AtCoder Beginner Contest 295
    ThreeDaysAgo我们定义一个只由数字构成的字符串中的字符能够被重排成相同的两份,我们称这个字符串是个好字符串,比如12341234现在给定一个字符串\(S\),找出所有的\([l,r]\),使得在这段区间中的子段是个好字符串题解:思维+组合计数首先我们根据题意得到:一个好字符串中所有相......
  • Atcoder题解:Agc002_f
    我们可以把这个理解成一种类似卡塔兰数的形式,我们发现,被安排的\(0\)球总数\(i\)和已经出现的颜色种数\(j\)在任意时刻都必须满足\(i\gej\)。然后就可以\(dp\)了,我们每次钦定下一个转移的球是某种颜色。如果下一个转移的球不是\(0\),那么我们就一次性把后面所有这种颜色......
  • Atcoder题解:Agc004_e
    \[吓死我了,还以为写了半天的被自己删掉了\]\[但是\text{Ctrl+S}会保存草稿啊\]\[以后一定要保留这个好习惯\]第一步转化题意,我们把“所有机器人移动”转化成“出口带着边框移动”,而在出口运动过程中超出边框的机器人,就“死”了。然后我们发现,出口运动过程中,假设出口目前走到......
  • Atcoder题解:Agc013_e
    我们考虑转化题意,一个合法的将\(1\simN\)划分成长度依次为\(a_1,a_2,\cdotsa_k\)的小区间,对答案的贡献为\(a_1^2a_2^2\cdotsa_k^2\)。化贡献为方案数,我们在每个长度为\(a_i\)的小区间内放置两个独立的标记,每个合法的划分方案对放置标记方案种数的贡献恰好是其对最终答......
  • AtCoder 板刷 / vp 记录
    ARC104AtCoder传送门A题解一道小学数学题,$X=\frac{A+B}{2},Y=\frac{A-B}{2}$。B题解一道暴力题。发现子串合法的充要条件是$cnt_{\text{A}}=cnt_{\text{T}}\landcnt_{\text{G}}=cnt_{\text{C}}$,暴力统计即可。C题解简单区间dp。发现$[1,2n]$可以拆......