• 思路:
    这种题目就考我们首先想到一个性质。这题其实容易想到:超限的菜最多只有一个,再加上这题有容斥那味,就枚举超限的菜然后dp就做完了。
    推式子能力还是不行,要看题解。
    式子还需要一个优化,就是废除冗余状态将二维化一维。

  • 代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105;
const int M=2005;
ll mod=998244353,a[N][M],s[N],g[N][M],dp[N][M];
int main() {
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=m;j++) {
			scanf("%lld",&a[i][j]);
			s[i]=(s[i]+a[i][j])%mod;
		}
	}
	ll less=0;
	for(int x=1;x<=m;x++) {
		memset(dp,0,sizeof(dp));
		dp[0][n]=1;
		for(int i=1;i<=n;i++) {
			for(int j=n-i;j<=n+i;j++) {
				dp[i][j]=(dp[i-1][j]+a[i][x]*dp[i-1][j-1]+(s[i]-a[i][x])*dp[i-1][j+1])%mod;
			}
		}
		for(int j=n+1;j<=n*2;j++) less+=dp[n][j];
	}
	g[0][0]=1;
	for(int i=1;i<=n;i++) {
		g[i][0]=1;
		for(int j=1;j<=i;j++) {
			g[i][j]=(g[i-1][j]+s[i]*g[i-1][j-1])%mod;
		}
	}
	ll sum=0;
	for(int i=1;i<=n;i++) sum=(sum+g[n][i])%mod;
	sum=(sum-less)%mod;
	printf("%lld",(sum+mod)%mod);
	return 0;
}