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;
}

  

posted @ 2018-10-29 11:35  ~Silent  阅读(213)  评论(0编辑  收藏  举报
Live2D