博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CodeForces743E. Vladik and cards 二分+状压dp
阅读量:4647 次
发布时间:2019-06-09

本文共 1288 字,大约阅读时间需要 4 分钟。

这个题我们可以想象成_---___-----__的一个水柱它具有一遍优一遍行的性质因此可以用来二分最小值len,而每次二分后我们都要验根,we可以把这个水柱想成我们在每个数段里取前一段的那个数后一段有也不选,而且最后一个区间的第一个数一定可以使这个数区间对应的数,那么我们只要在某个位置上不选或选就可以啦,这we很容易想到2n的验根但是这样还不如打暴力,这时我们发现这个dfs是低效的他会很多进入等效状态这样的话我们就可以记忆化搜索了,那么何妨递推,由于我们知道f[pos][mask]中只要pos(位置),mask(二进制代表是否选过)确定那么就要他的最大值就行了,而状态转移分两种一是前面len或len+1,或前一个状态,那么只要每一个状态是最大值,那么我们就从前面推到最后就找到了,这样的话我们可以正向推来代替反向吸收,因为如果只有那样吸收也就只有那样推.

千万不要忘了0的特判以及状态转移的完全性.

时间复杂度o(8*log2n*28*n)

#include
#include
#include
#include
#include
#define MAXN 1001using namespace std;int f[MAXN][(1<<8)+10];int n,a[MAXN],full=(1<<8)-1;bool had[10];vector
pos[10];inline void pre(){ scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); had[a[i]]=1; pos[a[i]].push_back(i); }}inline int Max(int x,int y){ return x>y?x:y;}inline int get(int p,int len){ int now=lower_bound(pos[a[p]].begin(),pos[a[p]].end(),p)-pos[a[p]].begin(); int ans=now+len-1; if(pos[a[p]].size()-1
>3; for(int i=1;i<=8;i++) if(had[i])ans++; while(l<=r) { int mid=(l+r)>>1,x=judge(mid); ans=Max(x,ans); if(x) l=mid+1; else r=mid-1; } printf("%d",ans);}int main(){ pre(); work(); return 0;}

 

转载于:https://www.cnblogs.com/TSHugh/p/7106544.html

你可能感兴趣的文章
四年时光,匆匆而过
查看>>
【php】【psr】psr1 基础编码规范
查看>>
WAF SSI
查看>>
LDAP & it's implementation
查看>>
Apache HttpComponents中的cookie匹配策略
查看>>
冰封的海盗攻略
查看>>
Netty4.x中文教程系列(四) 对象传输
查看>>
linux下find命令使用举例、
查看>>
GET请求在Tomcat中的传递及URI传递
查看>>
ubuntun 服务器与Mac
查看>>
重温JSP学习笔记--与日期数字格式化有关的jstl标签库
查看>>
java-Date-DateFormat-Calendar
查看>>
封装CLLocationManager定位获取经纬度
查看>>
我的第一篇博客-(Eclipse中或Myeclipse中如果不小心删除了包那可怎么办?)
查看>>
对easyui datagrid组件的一个小改进
查看>>
类似以下三图竞争关系的IT企业
查看>>
清明节
查看>>
ubuntu如何安装svn客户端?
查看>>
javascript之非构造函数的继承
查看>>
C#实现 单点登录(SSO)
查看>>