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 j th, total remaining columns chose k th
wron [i] [j] [ k] represents the current enumeration to the first i row, column selection unlawful j 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 , k 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; }