LOJ#6433. 「PKUSC2018」最大前缀和 状压dp
原文链接https://www.cnblogs.com/zhouzhendong/p/LOJ6433.html
题解
枚举一个集合 S ,表示最大前缀和中包含的元素集为 S ,然后求出有多少个排列是这样的。
对于左边和右边分别考虑,我们可以发现:
左边:每一个后缀和都 >=0
右边:每一个前缀和都 <0
然后就只需要用两个 dp 分别求出每一个集合的元素的排列中分别满足上述条件的方案数即可。
注意一下题目要求最大前缀和非空。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include <bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; int read(){ int x=0,f=1; char ch= getchar (); while (! isdigit (ch)&&ch!= '-' ) ch= getchar (); if (ch== '-' ) f=0,ch= getchar (); while ( isdigit (ch)) x=(x<<1)+(x<<3)+(ch^48),ch= getchar (); return f?x:-x; } const int N=20,mod=998244353; int n,a[N]; int Log[1<<N],sum[1<<N],dp1[1<<N],dp2[1<<N]; void Add( int &x, int y){ if ((x+=y)>=mod) x-=mod; } int main(){ n=read(); for ( int i=0;i<n;i++) a[i]=read(); for ( int i=2;i<(1<<n);i++) Log[i]=Log[i>>1]+1; for ( int i=1;i<(1<<n);i++) sum[i]=sum[i^(i&-i)]+a[Log[i&-i]]; dp1[0]=1; for ( int i=0;i<n;i++) dp2[1<<i]=1; for ( int i=1;i<(1<<n);i++) for ( int j=0;j<n;j++) if (i>>j&1){ if (sum[i]<0) Add(dp1[i],dp1[i^(1<<j)]); if (sum[i]-a[j]>=0) Add(dp2[i],dp2[i^(1<<j)]); } int ans=0,base=(1<<n)-1; for ( int i=1;i<(1<<n);i++) ans=(1LL*sum[i]*dp2[i]%mod*dp1[i^base]+ans)%mod; ans=(ans+mod)%mod; printf ( "%d" ,ans); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· DeepSeek本地性能调优
· 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略