ARC102EStop. Otherwise...

Posted asuldb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARC102EStop. Otherwise...相关的知识,希望对你有一定的参考价值。

题目

题意:给定$n$个没有区别的$K$面骰子,对于$i\in [2,2K]$求出有多少种骰子序列使得任意两个骰子的点数和不为$i$

考虑对于一种点数限制$i$,如果使用了点数为$j$的骰子,那么点数为$i-j$的骰子就不能使用了

于是对于一种限制$i$,我们可以把$1$到$K$的点数$j$分一下类

  • \(j\neq i-j,i-j\in [1,K]\),即$j$和$i-j$是两种不同的合法点数,则这两种点数只能出现一种

  • \(i-j\notin [1,K]\),即$j$这种点数的出现没有限制

  • \(i-j=j\),即$i=2j$,这个时候点数$j$只能出现一次

我们发现对于不同的$i$,都能分成这三类,且第三类会出现当且仅当$i$是偶数时

于是我们可以对前两种情况进行讨论

我们记第一种情况点数对有$cnt1$对,第二种情况点数有$cnt2$种

假设我们有两个数组,一个$dp_i,j$表示用不超过$i$对互斥点数对凑出$j$个数有多少情况,$f_i,j$表示用$i$种点数凑成$j$个数有多少情况,我们的答案就是

\(\sum_j=0^ndp_cnt1,j\times f_cnt2,n-j\)

当$i$为偶数的时候,还需要加上$\sum_j=0^dp_cnt1,j\times f_cnt2,n-1-j\(,即空出一个数给\) \frac2$的请况

考虑$f,dp$如何求出

$f$比较好求,显然有$f_i,j=\sum_k=0^jf_i-1,k$,即对于第$i$种点数枚举一下它选了多少个

$dp$表示的含义是互斥点数对,于是对于一对互斥点数对,可以是出现两种点数之一,于是$dp_i,j=dp_i-1,j+2\times\sum_k=0^dp_i-1,k$,即枚举这一对点对选了多少个,由于两种都可以填,所以要乘$2$

代码

#include<bits/stdc++.h>
#define re register
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
inline int read() 
	char c=getchar();int x=0;while(c<‘0‘||c>‘9‘) c=getchar();
	while(c>=‘0‘&&c<=‘9‘) x=(x<<3)+(x<<1)+c-48,c=getchar();return x;

const int mod=998244353;
const int maxn=2005;
int n,m,a[maxn];
int dp[maxn][maxn],f[maxn][maxn];
inline int qm(int x) return x>=mod?x-mod:x;
inline int dqm(int x) return x<0?x+mod:x;
inline int calc(int n,int a,int b) 
	int now=0;
	for(re int j=0;j<=n;j++)
		now=qm(now+1ll*dp[a][j]*f[b][n-j]%mod);
	return now;

int main() 
	scanf("%d%d",&m,&n);
	a[0]=1;dp[0][0]=1;for(re int i=1;i<=m;i++) dp[i][0]=1;
	for(re int i=1;i<=m;i++) 
		for(re int j=1;j<=n;j++)
			a[j]=qm(a[j-1]+dp[i-1][j]);
		for(re int j=1;j<=n;j++)
			dp[i][j]=qm(2ll*a[j-1]%mod+dp[i-1][j]);
	
	for(re int i=0;i<=m;i++) f[i][0]=1;
	for(re int i=1;i<=m;i++)
		for(re int j=1;j<=n;j++)
			f[i][j]=qm(f[i][j-1]+f[i-1][j]);
	int cnt1=0,cnt2=0,ans=0;
	for(re int i=2;i<=2*m;++i) 
		cnt1=cnt2=0;
		for(re int j=1;j<=m;j++) 
			if(i-j==j) continue;
			if(i-j>=1&&i-j<=m) 
				if(j<i-j) ++cnt1;
			
			else ++cnt2;
		
		ans=calc(n,cnt1,cnt2);
		if(!(i&1)) ans=qm(ans+calc(n-1,cnt1,cnt2));
		printf("%d\n",ans);
	
	return 0;



以上是关于ARC102EStop. Otherwise...的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Regular Contest (ARC102) E - Stop. Otherwise... 排列组合 动态规划

[arc102E]Stop. Otherwise...[容斥+二项式定理]

ARC102E - Stop. Otherwise... 组合计数

ARG102E:Stop. Otherwise...

atcoderAll Your Paths are Different Lengths[arc102D](乱搞)

ARC102D Revenge of BBuBBBlesort!