CSP2019 Emiya family meal explanations today

This problem in the examination room only O (n ^ 3 m), took 84 minutes. .

Talk about 84 minutes, consider inclusion and exclusion, illegal program subtracts the total program, i.e. every ingredients enumerated, seek to do with it exceeds \ (\ lfloor \ frac {k } {2} \ rfloor \) courses the program number, subtracted from the total program.

First one kind of ingredients enumerated x, provided F [i] [j] [k] is the i before cooking methods, do dishes j, where k is the channel ingredients do x number of programs, the transfer account of the kind of cooking i cooking program does not / do dishes of food x / dishes do three cases of other ingredients. Finally, all of f [n] [j] [j / 2 + 1 ~ n] is not legal and that is the case.

Consider how optimization, there is provided a solution in the dish k, where t x food dish is done, then if and only if \ (t> \ lfloor \ frac {k} {2} \ rfloor \) when the scheme is not legal, that \ (2t-k> 0 \ ) is not legitimate when. Then we need only program recorded in the DP \ (K-2T \) values, takes the final state is greater than 0 to the number of programs. I.e. set F [i] [j] is the i consider only before cooking methods, programs \ (2t-k \) the number of programs is j. Considering the above three cases are respectively transferred proceeds to f [i + 1] [j ] / f [i + 1] [j + 1] / f [i + 1] [j-1] can.

Code:

#include<bits/stdc++.h>
using namespace std;
#define N 107
#define M 2007
#define ll long long
const ll mod=998244353;
ll a[N][M],sum[N],f[N][N<<1];
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]);
            sum[i]=(sum[i]+a[i][j])%mod;
        }
    ll ans=0;
    for(int now=1;now<=m;now++)
    {
        memset(f,0,sizeof(f));
        f[0][N]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=N-n;j<=N+n;j++)
            {
                f[i][j]=(f[i][j]+f[i-1][j])%mod;
                f[i][j]=(f[i][j]+f[i-1][j-1]*a[i][now])%mod;
                f[i][j]=(f[i][j]+f[i-1][j+1]*(sum[i]+mod-a[i][now]))%mod;
            }
        }
        for(int i=1;i<=n;i++)
            ans=(ans+f[n][N+i])%mod;
    }
    ll res=1;
    for(int i=1;i<=n;i++)
        res=res*(sum[i]+1)%mod;
    res=(res+mod-1)%mod;
    res=(res+mod-ans)%mod;
    printf("%lld\n",res);
    return 0;
}

Guess you like

Origin www.cnblogs.com/lishuyu2003/p/11891877.html