How difficult it is to find three questions about \ (fat \) in a world full of cadoli
Today's meal at Emiya's house
A very good inclusion exclusion + \ (dp \) problem
Considering the third limitation, it is found that at most one column is illegal, so we can enumerate which column is illegal
Then the next task is to find the total number of schemes - the number of illegal schemes
First, consider how to calculate the number of illegal schemes
Let \ (s_i \) represent \ (\ sum a_{i,j} \) of each row, and \ (col \) represent the illegal column enumerated
Let \ (f_{i,j,k} \) indicate that considering row \ (I \), row \ (j \) is selected for the illegal column, and a total of \ (k \) rows are selected for the remaining columns
Then you can get the transfer
\(f_{i,j,k}=f_{i-1,j,k}+a_{i,col}\times f_{i-1,j-1,k}+(s_i-a_{i,col})\times f_{i-1,j,k-1}\)
Then, for an illegal column \ (col \), its scheme number is \ (\ sum \ limits {UJ > k} f {n, J, K} \)
Next, consider how to calculate the total number of schemes
Let \ (g_{i,j} \) mean that considering the number of schemes in row \ (j \) is selected in column \ (I \), the transfer is simpler
\(g_{i,j}=g_{i-1,j}+s_i\times g_{i-1,j-1}\)
The total number of schemes is \ (\ sum \ limits {UJ = 1} ^ {n}g {n, J} \)
In this case, the complexity is \ (O(n^3m) \), the expected score is \ (84 \), and the enumeration times shall be optimized
It is found that it is meaningless to know the specific value of \ (j,k \) in \ (f_{i,j,k} \),
Then consider removing one dimension and changing it into \ (f_{i,j} \), which means that considering the \ (I \) row, the difference between the number of rows selected in the illegal column and the number of rows selected in other columns is \ (j \), that is, the original \ (j-k \)
In this way, the transfer becomes \ (O(n^2m) \) and the estimated score \ (100 \)
code#include<cstdio> #include<cstring> #include<iostream> #define LL long long const int NN=105,MM=2005; const LL mod=998244353; namespace AE86{ auto 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<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; }; auto write=[](LL x,char opt='\n'){ char ch[20];short len=0;if(x<0)x=~x+1,putchar('-'); do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); for(short i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt); }; }using namespace AE86; int n,m,a[NN][MM]; LL ans,s[NN],f[2][NN<<1],g[2][NN],tot,r[NN][MM]; namespace WSN{ inline short main(){ // freopen("meal.in","r",stdin); // freopen("meal.out","w",stdout); n=read();m=read(); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j) a[i][j]=read(),s[i]=(s[i]+a[i][j])%mod; for(int j=1;j<=m;++j) r[i][j]=(s[i]-a[i][j]+mod)%mod; } for(int col=1;col<=m;++col){ memset(f,0,sizeof(f));f[0][n]=1; for(int i=1;i<=n;++i) for(int j=n-i;j<=n+i;++j) f[i&1][j]=(f[(i-1)&1][j]+(j>0?f[(i-1)&1][j-1]*a[i][col]%mod:0)+(j<n*2?f[(i-1)&1][j+1]*r[i][col]%mod:0))%mod; int tmp=0; for(int j=1;j<=n;++j) tmp=(tmp+f[n&1][n+j])%mod; ans=(ans+tmp)%mod; } g[0][0]=1; for(int i=1;i<=n;++i) for(int j=0;j<=n;++j) g[i&1][j]=(g[(i-1)&1][j]+(j>0?s[i]*g[(i-1)&1][j-1]%mod:0))%mod; for(int j=1;j<=n;++j) tot=(tot+g[n&1][j])%mod; write((tot-ans+mod)%mod); return 0; } } signed main(){return WSN::main();}
\(tips\):
Tolerance, exclusion, dynamic programming
Gate of Babylon
More classic content exclusion topics, consider the transformation of topic meaning
There is an indefinite equation \ (x_1+x_2+...+x_n\leq m \), some of which \ (x_i \) are limited by \ (x_i\leq b_i \), and there are several nonnegative integer solutions of the legal indefinite equation.
Note: the following solutions are non negative integer solutions
First, consider how many solutions there are for the indefinite equation \ (x+y+z=10 \). It can be known that there are \ (C_12^2 \) solutions by the inserting plate method
Then it can be seen that there are \ (C {m + n-1} ^ {n-1} \) solutions to the indefinite equation \ (x_1+...+x_n=m \) with \ (n \) unknowns
Considering the solution of \ (x+y+z\leq 10 \), the board inserting method is also used to obtain \ (C_13^3 \), because a pile can be selected to free up space
Then there are \ (C {m + n} ^ {n} \) solutions of \ (x_1+...+x_n\leq m \) without restriction
Continue to consider the solution of \ (x+y+z\leq 10 \) with restrictions, assuming \ (x\leq 6 \)
This problem can be considered inclusive and exclusive. Subtracting the solution beyond the limit from the total solution is the limited solution. Consider calculating the solution beyond the limit
We can complete a new \ (xx=x+7 \), then for \ (x\leq 6 \), there are \ (XX < 0 \), that is, the number of solutions of \ (xx+7+y+z\leq 10 \) is \ (0 \),
Then, if you continue to use the board inserting method, the number of solutions exceeding the limit is \ (C_6^3 \), then the number of solutions of the last \ (x+y+z\leq 10 \) and \ (x\leq 6 \) is \ (C_13^3-C_6^3 \)
If there are multiple sets of restrictions in the topic, consider using tolerance and exclusion, odd subtraction and even addition, \ (2^T \) to enumerate all possible states, and then calculate the number of legal solutions
code#include<cstdio> #include<cstring> #include<iostream> #define int long long const int NN=1e5+5; using namespace std; namespace AE86{ auto 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<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; }; auto write=[](int x,char opt='\n'){ char ch[20];short len=0;if(x<0)x=~x+1,putchar('-'); do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); for(short i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt); }; }using namespace AE86; int n,m,t,mod,b[16],ans; namespace Math{ int h[NN],v[NN]; auto qmo=[](int a,int b,int ans=1){ int c=mod;for(;b;b>>=1,a=a*a%c)if(b&1)ans=ans*a%c; return ans; }; auto inv=[](int x){return qmo(x,mod-2);}; auto prework=[](){ h[0]=h[1]=1; v[0]=v[1]=1; for(int i=2;i<mod;++i) h[i]=h[i-1]*i%mod; for(int i=2;i<mod;++i) v[i]=v[i-1]*inv(i)%mod; }; auto C=[](int n,int m){return (n<m||n<0||m<0)?0:h[n]*v[n-m]%mod*v[m]%mod;}; inline int lucas(int n,int m){return m?lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod:1;} }using namespace Math; namespace WSN{ inline short main(){ n=read(); t=read(); m=read(); mod=read(); prework(); for(int i=1;i<=t;i++) b[i]=read(); for(int i=0;i<(1<<t);i++){ int tmp=m,bs=(__builtin_popcount(i)&1)?-1:1; for(int j=1;j<=t;j++)if(i&(1<<j-1))tmp-=(b[j]+1); ans=(ans+bs*lucas(tmp+n,n)+mod)%mod; } write(ans); return 0; } } signed main(){return WSN::main();}
Excalibar
Direct bipartite graph maximum weight independent set, just run network flow. As for why I look at others Detailed proof Yes, so if you want to know why, just turn right
Code (the most distinctive code among the three questions. Because the protagonist of the question is Dumbo, I still couldn't help but win the second prize)#include<cstdio> #include<cstring> #include<iostream> #define int long long const int NN=5e5+5,inf=1e18; using namespace std; namespace Lancer{ auto Excalibar=[](){ 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<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; }; auto Enuma_Elish=[](int x,char opt='\n'){ char ch[20];short len=0;if(x<0)x=~x+1,putchar('-'); do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); for(short i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt); }; }using namespace Lancer; int n,m,w[101][101],ans; int dx[4]={0,0,-1,1}, dy[4]={-1,1,0,0}; struct Caster{int to,val,next;}e[NN<<1];int head[NN],rp=1; auto add=[](int x,int y,int z){ e[++rp]=Caster{y,z,head[x]};head[x]=rp; e[++rp]=Caster{x,0,head[y]};head[y]=rp; }; namespace Archer{ int HD[NN],q[NN],h,t,dis[NN],S,T; auto bfs=[](){ memset(dis,0x3f,sizeof(dis)); memcpy(head,HD,sizeof(head)); q[h=t=1]=S; dis[S]=0; while(h<=t){ int x=q[h++]; for(int i=head[x];i;i=e[i].next)if(e[i].val) if(dis[e[i].to]>dis[x]+1) dis[e[i].to]=dis[x]+1,q[++t]=e[i].to; if(x==T) return 1; } return 0; }; inline int dfs(int x,int in){ if(x==T) return in; int rest=in,go; for(int i=head[x];i;head[x]=i=e[i].next)if(e[i].val){ int y=e[i].to,v=e[i].val; if(dis[y]==dis[x]+1){ go=dfs(y,min(rest,v)); if(go) e[i].val-=go,e[i^1].val+=go,rest-=go; else dis[y]=0; }if(!rest) break; } return in-rest; } auto dinic=[](int ans=0){ memcpy(HD,head,sizeof(HD)); while(bfs()) ans+=dfs(S,inf); return ans; }; auto id=[](int x,int y){return (x-1)*m+y;}; }using namespace Archer; namespace Saber{ inline short main(){ n=Excalibar(); m=Excalibar(); S=n*m+1; T=S+1; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) w[i][j]=Excalibar(),ans+=w[i][j]; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) if((i+j)&1){ add(S,id(i,j),w[i][j]); for(int k=0;k<4;k++){ int x=i+dx[k],y=j+dy[k]; if(x>0&&x<=n&&y>0&&y<=m) add(id(i,j),id(x,y),inf); } } else add(id(i,j),T,w[i][j]); Enuma_Elish(ans-dinic()); return 0; } } signed main(){return Saber::main();}