数据过水,请求加强数据
查看原帖
数据过水,请求加强数据
761283
Rikka_lyly楼主2023/10/5 11:39

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);
}

2023/10/5 11:39
加载中...