状压最大前缀和由哪些数组成,保证最大前缀和合法
#include<cstdio>
using namespace std;
const int mod=998244353;
int a[25],F[1200005],G[1200005];
int main(){
int n;
scanf("%d",&n);
for (int i=0; i<n; i++) scanf("%d",&a[i]);
int Max=(1<<n)-1;
for (int i=0; i<n; i++) F[1<<i]=1;
for (int i=0; i<(1<<n); i++){
long long Sum=0;
for (int j=0; j<n; j++) if (i&(1<<j)) Sum+=a[j];
for (int j=0; j<n; j++) if (!(i&(1<<j)) && Sum>0) (F[i|(1<<j)]+=F[i])%=mod;
}
G[0]=1;
for (int i=0; i<(1<<n); i++){
long long Sum=0;
for (int j=0; j<n; j++) if (i&(1<<j)) Sum+=a[j];
for (int j=0; j<n; j++) if (!(i&(1<<j)) && Sum<=0 && Sum+a[j]<=0) (G[i|(1<<j)]+=G[i])%=mod;
}
int ans=0;
for (int i=1; i<(1<<n); i++){
long long Sum=0;
for (int j=0; j<n; j++) if (i&(1<<j)) Sum+=a[j];
Sum%=mod;
(Sum+=mod)%=mod;
(ans+=Sum%mod*F[i]%mod*G[Max^i]%mod)%=mod;
}
printf("%d\n",ans);
return 0;
}
原文:https://www.cnblogs.com/silenty/p/9869736.html