题解:P10242 [THUSC 2021] Emiya 家明天的饭

· · 题解

首先发现人很少,所以我们考虑菜对人而不是人对菜。设一个菜喜欢一个人当且仅当这个人喜欢这个菜。

p_i 为第 i 道菜喜欢的人的集合。

答案即为:

\max_S(\sum_{i\in S}\sum_{S\subseteq p_j}a_{i,j}) 设 $f_{i,s}=\sum\limits_{p_j=s}a_{i,j}$。 答案为: $$\max_S(\sum_{i\in S}\sum_{S\subseteq T}f_{i,T})$$ 发现 $\sum_{S\subseteq T}f_{i,T}$ 就是且运算的 FWT。然后就做完了。 ```cpp #include<bits/stdc++.h> using namespace std; #define ll long long #define rep(i,a,b) for(int i=(a);i<=(b);i++) const int N=22,NN=(1<<N)+10,M=1e6+10; int n,m; int a[N][M],p[M]; ll f[N][NN]; void FWT(ll *f,int len){ for(int mid=1;mid<len;mid<<=1){ for(int i=0;i<len;i+=(mid<<1)){ for(int j=0;j<mid;j++){ f[i+j]+=f[i+j+mid]; } } } } int main(){ scanf("%d%d",&n,&m); rep(i,1,n){ rep(j,1,m){ scanf("%d",&a[i][j]); if(a[i][j]!=-1)p[j]|=(1<<(i-1)); } } rep(i,1,n){ rep(j,1,m){ f[i][p[j]]+=a[i][j]; } FWT(f[i],1<<n); } ll ans=0; rep(s,0,(1<<n)-1){ ll tans=0; rep(i,1,n){ if(!(s&(1<<(i-1))))continue; tans+=f[i][s]; } ans=max(ans,tans); } printf("%lld",ans); return 0; } ```