BZOJ 5369: [Pkusc2018]最大前缀和
状压最大前缀和由哪些数组成,保证最大前缀和合法
#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; }