洛谷P5369 [PKUSC2018]最大前缀和 [DP]
思路
这么一道签到题竟然没切掉真是丢人呢……
首先有一个\(O(3^n)\)的SB方法,记录\(dp_{S,T}\)表示已经填进去了\(S\),当前最大前缀和集合为\(T\),随便转移。太简单了就不细讲了。
挖掘一下题目的性质:一个序列必然可以被分成两部分:前面的前缀和&后面的部分。
后面的部分满足一个性质:任意前缀和都<0,所以很容易DP。
前面可以考虑每次往数列前面加数,那么就必须要满足原来的数列总和\(\ge 0\),也很容易DP,具体可以见代码。
然后就做完了……我这都不会真是菜死了……
代码
#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 1100000
#define mod 998244353ll
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
char __sr[1<<21],__z[20];int __C=-1,__zz=0;
inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
inline void print(register int x)
{
if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
while(__z[++__zz]=x%10+48,x/=10);
while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
}
void file()
{
#ifdef NTFOrz
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifndef ONLINE_JUDGE
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;
int n;
int a[25];
int sum[sz];
ll f[sz],g[sz];
ll fac[sz];
void init(){fac[0]=1;rep(i,1,sz-1) fac[i]=fac[i-1]*i%mod;}
int main()
{
file();
init();
read(n);
rep(i,1,n) read(a[i]);
int N=(1<<n)-1;
rep(i,0,N) rep(j,0,n-1) if (i>>j&1) sum[i]+=a[j+1];
g[0]=1;
rep(i,0,N-1)
rep(j,1,n)
if (!(i>>(j-1)&1)&&sum[i|(1<<(j-1))]<0)
(g[i|(1<<(j-1))]+=g[i])%=mod;
f[0]=1;
rep(i,0,N-1)
if (sum[i]>=0)
rep(j,0,n-1)
if (!(i>>j&1))
(f[i|(1<<j)]+=f[i])%=mod;
ll ans=0;
rep(i,1,N) (ans+=f[i]*g[N^i]%mod*sum[i]%mod)%=mod;
cout<<(ans+mod)%mod;
return 0;
}
洛谷P5369 [PKUSC2018]最大前缀和 [DP]的更多相关文章
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 洛谷 P4072 [SDOI2016]征途 斜率优化DP
洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...
- 洛谷P1470 最长前缀
P1470 最长前缀 Longest Prefix 题目描述 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 ...
- 洛谷 P5469 - [NOI2019] 机器人(区间 dp+拉格朗日插值)
洛谷题面传送门 神仙题,放在 D1T2 可能略难了一点( 首先显然对于 P 型机器人而言,将它放在 \(i\) 之后它会走到左边第一个严格 \(>a_i\) 的位置,对于 Q 型机器人而言,将它 ...
- 洛谷P1880 石子合并(区间DP)(环形DP)
To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...
- 洛谷P1063 能量项链(区间DP)(环形DP)
To 洛谷.1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...
- 洛谷P1282 多米诺骨牌 (DP)
洛谷P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中 ...
- 【题解】洛谷P4158 [SCOI2009] 粉刷匠(DP)
次元传送门:洛谷P4158 思路 f[i][j][k][0/1]表示在坐标为(i,j)的格子 已经涂了k次 (0是此格子涂错 1是此格子涂对)涂对的格子数 显然的是 每次换行都要增加一次次数 那么当j ...
随机推荐
- 怎样给回调函数绑定this
在三种绑定this的方法中, Function.prototype.call() 和 Function.prototye.apply() 都是会立即执行该函数的, 但回调函数是不能立即执行的, 它只是 ...
- Linux自动运维工具Ansible的使用
Linux自动运维工具Ansible的使用 我们熟悉这个工具后, 可以很轻松的安装k8s. 一.介绍 ansible - run a task on a target host(s) Ansible是 ...
- hdu 4496 其实还是并查集
Problem Description Luxer is a really bad guy. He destroys everything he met. One day Luxer went to ...
- C# 延迟初始化 Lazy<T>
概念:延时初始化重点是延时,用时加载,意思是对象在使用的时候创建而不是在实例化的的时候才创建. 延时加载主要应用的场景: 数据层(ADO.NET或Entity Framework等ORM,Java ...
- 【Linux】Linux基本命令
一.Linux关机 shutdown -h 10 10min后关机 shutdown -h 10:00 10:00关机 shutdown -h now 或 halt 或 poweroff 立即关机 ...
- 小白_开始学Scrapy__原理
整体架构 引擎(Scrapy Engine),用来处理整个系统的数据流处理,触发事务. 调度器(Scheduler),用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回. 下载器(Dow ...
- SRX550路由器缓存满了无法在web页面操作解决方法
SRX550路由器缓存满了无法在web页面操作解决方法 首页出现下图为满的标志,我这个文档就是解决这中情况,让web页面可以操作的 1. 打开命令行,输入用户密码,进入路由器 注意:这里使用te ...
- CentOS7.X 搭建LAMP
第一部分搭建LAMP基础环境 1.检查CentOS是否为7.x版本 2.安装LAMP中的apache,采用yum源方法安装 yum install httpd httpd-devel A ...
- NORDIC BLE升级
NRF52832 SDK15.3.0 概述: 所谓DFU(Device Firmware Update),就是设备固件升级的意思,而OTA是DFU的一种类型,准确说,OTA的全称应该是OTA DFU, ...
- 配置tmux在机器重启后自动恢复tmux工作现场,告别重启恐惧症
1. 问题出现的背景 通过ssh远程登录服务器在上面工作,有时候很有可能由于网络断开而导致ssh链接断开,或者下班后想继续在家登录到服务器继续工作.这些情况都需要服务器保持我们的工作环境,比如,vim ...