LGP5664题解

Posted 欢迎来到lmppの小窝

tags:

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

厉害。

对于每一列选的数最多占一半,我们得设计一个三维 DP。然而状态刚好够,但是转移明显炸了(而且似乎还需要多项式?)

考虑正难则反,DP 不合法的方案数。总方案数很好算。

发现不合法的方案数只有某一列的出现次数超过一半,直接枚举这一列。设当前列为第 \\(k\\) 列。

\\(dp_i,x,y\\) 为前 \\(i\\) 行,当前列选了 \\(x\\) 个,其他列共选了 \\(y\\) 个的方案数。

再设第 \\(i\\) 行的 \\(a\\) 之和为 \\(S[i]\\),容易有:

\\[dp_i,x,y=dp_i-1,x,y+a[i][k]\\times dp_i-1,x-1,y+(S[i]-a[i][k])\\times dp_i-1,x,y-1 \\]

复杂度 \\(O(mn^3)\\),可以获得 \\(84\\) 分。

注意到在统计答案时计算的是 \\(\\sum_x>ydp_n,x,y\\),我们只关心 \\(x\\) 是否比 \\(y\\) 大,考虑重新设状态。

\\(dp_i,x\\) 表示前 \\(i\\) 行的选择中,当前列比其他列多选了 \\(x\\) 个(\\(x\\) 可以为负数)。转移方程和刚才几乎一致:

\\[dp_i,x=dp_i-1,x+a[i][k]\\times dp_i-1,x-1+(S[i]-a[i][k])\\times dp_i-1,x+1 \\]

复杂度 \\(O(mn^2)\\)

#include<cstdio>
typedef unsigned ui;
const ui M=105,mod=998244353;
ui n,m,S[M],a[M][2005],dp[M][M<<1],f[M][M];
inline ui DP(const ui&x)
	ui sum(0);dp[0][n]=1;
	for(ui i=1;i<=n;++i)
		const ui&c1=a[i][x],&c2=mod+S[i]-a[i][x];
		dp[i][n-i]=1ll*c2*dp[i-1][n-i+1]%mod;dp[i][n+i]=1ll*c1*dp[i-1][n+i-1]%mod;
		for(ui j=n-i+1;j<=n+i-1;++j)dp[i][j]=(dp[i-1][j]+1ull*c1*dp[i-1][j-1]+1ull*c2*dp[i-1][j+1])%mod;
	
	for(ui i=1;i<=n;++i)sum=(sum+dp[n][n+i])%mod;
	return sum;

signed main()
	ui sum(0);scanf("%d%d",&n,&m);
	for(ui i=1;i<=n;++i)for(ui j=1;j<=m;++j)scanf("%u",a[i]+j),S[i]=(S[i]+a[i][j])%mod;
	for(ui i=1;i<=m;++i)sum=(sum+DP(i))%mod;
	f[0][0]=1;
	for(ui i=1;i<=n;++i)
		f[i][0]=1;
		for(ui j=1;j<=i;++j)f[i][j]=(f[i-1][j]+1ll*S[i]*f[i-1][j-1])%mod;
	
	for(ui i=1;i<=n;++i)sum=(sum+mod-f[n][i])%mod;
	printf("%u",sum?mod-sum:0);

看了题解才会,太菜了/kk

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

每日题解 #16LGP2801 教主的魔法

LGP5437XR-2约定

LGP4518[JSOI2018]绝地反击

LGP4588[JSOI2018]扫地机器人

LGP5289口胡

LGP7582口胡