P5664 Emiya family meal today

P5664 Emiya family meal today

Cry QAQ this whole question of 12,345,678 days, the solution to a problem and blog sy is completed with the help of title QAQ

answer

Simplify the meaning of problems

> Gives a matrix of n * m, total of k is selected, can not be selected, requirements:

1. Each row can only choose one

2. Select up each column a

 

Calculated the number of legal program

Abstract understanding of what is such a thing

 

Solving ideas

Direct solution Mo was thinking, then it is difficult being contrary, we consider the total number of programs - the number of illegal schemes 

Consider There are no restrictions, we can easily take, but there are some among this scheme is not satisfied with 1, 2 also does not satisfy some, there are neither satisfied nor satisfied 1 2

We wish to meet a requirement 1, that is, we only pick one per line, and then we remove the premise of meeting the requirements of a program does not meet the number 2

That is:

Total program - the number of illegal schemes meet the total number of programs = 1 - 1 but does not satisfy satisfying number (the number of illegal programs) 2 programs

 

Solving process

1. how to meet the demand program number 1? ? ?

Set array TOT [i] [j] denotes the front i j-th row is selected from the maximum number of programs

SUM [i] denotes the total number of i-th row

Consider for each digit of the current i-th row can be selected or not selected, every election a will before the election had to form a new scheme (in fact, the principle of multiplication distribution), get recursive formula:

all [i] [j] = all [i-1] [j] + all [i-1] [j-1] * sum [i] 

 

2. how the number of seeking illegal scheme? ? ?

That is illegal does not meet the requirements 2, each column of more than one

Only one more than the actual one, because if there are> = more than two months, then the total number selected to> k, that is, there have been contradictory

So you can consider an enumeration illegal column

We set up illegal columns of the current enumeration of selected  th, total remaining columns chose  k th

wron [i] [j] [ k] represents the current enumeration to the first row, column selection unlawful  months, the remaining columns selected a total of  k number of programs, each enumeration to a new column, or the column not a choice, or choose not to legitimate this column, either select one of the remaining columns, get recursive formula:

crows [i] [j] [k] = crows [i-1] [j] [k]

                           + wron[ i-1 ][ j+1 ][ k ] * a[ i ][ line ]

                           + wron[ i-1 ][ j ][ k+1 ] * ( sum[ i ] - a[ i ][ line ] ) 

We actually do not care  j  , specific values, we only need to know their relative size just fine, we set up illegal columns than the rest of the j-th column of multiple-choice, unlawful column select the x + j th, then the rest x number of columns on the election, we only need to enumerate j like a recursive formula to read:

wron[ i ][ j ] = wron[ i-1 ][ j ]

                    + wron[ i-1 ][ j-1 ] * a[ i ][ line ]

                    + wron[ i-1 ][ j+1 ] * ( sum[ i ] - a[ i ][ line ] )

Note that most illegal columns other than the i-th row multiple choice, less choice will be up to the i-th row than any other, that is, in fact, j ranges  [-i, i]   , because the array index is not negative, we consider add unified index n, j enumeration range is [ni, n + i] 

Then the number of illegal schemes that j> 0, minus the total number of programs like

 

Finally, note modulo like

 

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<string>
#include<cstring>
using namespace std;
typedef long long ll;

inline ll read()
{
    ll ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

const int mod=998244353;
int n,m;
ll a[105][2005];
ll sum[105];
ll tot[105][2005];
ll wron[105][400];
ll ans=0;

int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++){
          a[i][j]=read();
          sum[i]=(sum[i]+a[i][j])%mod;
      }
    tot[0][0]=1;
    for(int i=1;i<=n;i++)
      for(int j=0;j<=n;j++)
      tot[i][j]=((tot[i-1][j]%mod+tot[i-1][j-1]*sum[i]%mod)%mod+mod)%mod;
    for(int i=1;i<=n;i++)
      ans=(ans+tot[n][i])%mod;
     
    for(int l=1;l<=m;l++){
        memset(wron,0,sizeof(wron));
        wron[0][n]=1;
        for(int i=1;i<=n;i++)
           for(int j=n-i;j<=n+i;j++)
           wron[i][j]=((wron[i-1][j]+wron[i-1][j-1]*a[i][l]%mod+wron[i-1][j+1]*(sum[i]-a[i][l])%mod)%mod+mod)%mod;  
        for(int j=n+1;j<=n*2;j++)
           ans=((ans-wron[n][j])%mod+mod)%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/xiaoyezi-wink/p/12085042.html