zoukankan      html  css  js  c++  java
  • bzoj5369: [PKUSC2018]最大前缀和 (状压dp)

    www.cnblogs.com/shaokele/


    bzoj5369: [PKUSC2018]最大前缀和##

      Time Limit: 20 Sec
      Memory Limit: 512 MB
      p1
     
      p2
      

    题目地址:  bzoj5369: [PKUSC2018]最大前缀和

    题目大意:   全排列,求每次最大前缀之和####

    题解:

      考试时没A 哭唧唧
      
      其实就是一个状态压缩
      
      具体看代码
      


    AC代码

    #include <cstdio> 
    using namespace std;
    const int N=21,mo=998244353;
    int n;
    int a[N],f[1<<N],g[1<<N];
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	//f[S] 表示取S的状态使前缀>0的方案数 
    	//g[S] 表示取S的状态使前缀<=0的方案数
    	for(int i=1;i<(1<<n);i++){
    		int now=0,s=0;
    		for(int j=1;j<=n;j++)
    			if(i&(1<<(j-1)))
    				now+=a[j],s++;
    		if(s==1)f[i]=1;
    		else
    			for(int j=1;j<=n;j++)
    				if((i&(1<<(j-1))) && now-a[j]>0)
    					f[i]=(f[i]+f[i^(1<<(j-1))])%mo;    //当前i的情况可以从f[i^(1<<(j-1))]推过来 
    	}
    	g[0]=1;
    	for(int i=1;i<(1<<n);i++){
    		int now=0,s=0;
    		for(int j=1;j<=n;j++)
    			if(i&(1<<(j-1)))
    				now+=a[j],s++;
    		if(now>0)g[i]=0;
    		else{
    			if(s==1){
    				g[i]=1;
    				continue; 
    			} 
    			for(int j=1;j<=n;j++)
    				if(i&(1<<(j-1)))
    					g[i]=(g[i]+g[i^(1<<(j-1))])%mo;   //同 f 
    		}
    	}
    	int ans=0;
    	for(int i=1;i<(1<<n);i++){ 
    		int now=0,del=(1ll*f[i]*g[(1<<n)-1-i])%mo;   //now:值  del:方案数 
    		for(int j=1;j<=n;j++)
    			if(i&(1<<(j-1)))now=(now+a[j]+mo)%mo;
    		now=(1ll*now*del)%mo;
    		ans=(ans+now)%mo;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Nhibernate对应关系参数介绍
    jquery mobile 登陆后页面验证
    jquery mobile radio,checkbox button 样式设置
    jquery mobile button样式设置
    Ext 三级联动 及附值
    store操作
    Javascript中try finally的细微差别
    mysql entity framework生成画面崩溃
    PYTHON推导生成
    PYTHON修饰器
  • 原文地址:https://www.cnblogs.com/shaokele/p/9157644.html
Copyright © 2011-2022 走看看