rt,本蒟蒻用mn^3的时间复杂度水过了。 主要在这一句
if (k > 0)
f[i][j][k] += f[i - 1][j][k - 1] * (sumrow[i] - a[i][col]);//这里少取模就能过
完整代码
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
#define ull unsigned long long
#define MAXN 105
#define MAXM 2010
const ll mod = 998244353;
inline int read() //快读
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = x * 10 + ch - 48;
ch = getchar();
}
return x * f;
}
int n, m;
int a[MAXN][MAXM];
ll sumrow[MAXN];
ll f[MAXN][MAXN][MAXN]; //某一列,前i个,这一列选j个,其余列选k个
ll illegal;
ll g[MAXN][MAXN]; //考虑到第i列,选了j种菜
int main()
{
n = read(), m = read();
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
a[i][j] = read();
sumrow[i] = (sumrow[i] + a[i][j]) % mod;
}
}
f[0][0][0] = 1;
for (int col = 1; col <= m; col++)
{
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= i; j++)
{
for (int k = 0; k <= i - j; k++)
{
f[i][j][k] = f[i - 1][j][k];
if (j > 0)
f[i][j][k] += f[i - 1][j - 1][k] * a[i][col];
if (k > 0)
f[i][j][k] += f[i - 1][j][k - 1] * (sumrow[i] - a[i][col]);//这里少取模就能过
f[i][j][k] %= mod;
// printf("f[%d][%d][%d]=%d\n", i, j, k, f[i][j][k]);
}
}
}
for (int j = 0; j <= n; j++)
{
for (int k = 0; k <= min(n - j, j - 1); k++)
{
illegal = (illegal + f[n][j][k]) % mod;
}
}
}
// printf("illegal=%d\n", illegal);
g[0][0] = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= i; j++)
{
g[i][j] = g[i - 1][j];
if (j > 0)
g[i][j] += g[i - 1][j - 1] * sumrow[i];
g[i][j] %= mod;
// printf("g[%d][%d]=%d\n", i, j, g[i][j]);
}
}
ll ans = 0;
for (int j = 1; j <= n; j++)
{
ans += g[n][j];
ans %= mod;
}
ans -= illegal;
ans = (ans % mod + mod) % mod;
printf("%d\n", ans);
}