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

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

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

#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 1001
using namespace std;
int f[MAXN][(<<)+];
int n,a[MAXN],full=(<<)-;
bool had[];
vector<int>pos[];
inline void pre()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
had[a[i]]=;
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-;
if(pos[a[p]].size()-<ans)return -;
return pos[a[p]][ans];
}
int judge(int len)
{
memset(f,,sizeof(f));
for(int i=;i<n;i++)
{
int to=get(i+,len);
if(to!=-)f[to][(<<(a[i+]-))]=Max(f[i][]+len,f[to][(<<(a[i+]-))]);
to=get(i+,len+);
if(to!=-)f[to][(<<(a[i+]-))]=Max(f[i][]+len+,f[to][(<<(a[i+]-))]);
for(int j=;j<full;j++)
if(f[i][j])
{
f[i+][j]=Max(f[i+][j],f[i][j]);
if(j&(<<(a[i+]-)))continue;
to=get(i+,len);
if(to!=-)f[to][j|(<<(a[i+]-))]=Max(f[i][j]+len,f[to][j|(<<(a[i+]-))]);
to=get(i+,len+);
if(to!=-)f[to][j|(<<(a[i+]-))]=Max(f[i][j]+len+,f[to][j|(<<(a[i+]-))]);
}
f[i+][full]=Max(f[i+][full],f[i][full]);
}
return f[n][full];
}
void work()
{
int ans=,l=,r=n>>;
for(int i=;i<=;i++)
if(had[i])ans++;
while(l<=r)
{
int mid=(l+r)>>,x=judge(mid);
ans=Max(x,ans);
if(x)
l=mid+;
else
r=mid-;
}
printf("%d",ans);
}
int main()
{
pre();
work();
return ;
}

CodeForces743E. Vladik and cards 二分+状压dp的更多相关文章

  1. hdu 3681(bfs+二分+状压dp判断)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 思路:机器人从出发点出发要求走过所有的Y,因为点很少,所以就能想到经典的TSP问题.首先bfs预 ...

  2. 2018.08.19 NOIP模拟 dp(二分+状压dp)

    Dp 题目背景 SOURCE:NOIP2015-SHY-10 题目描述 一块土地有 n 个连续的部分,用 H[1],H[2],-,H[n] 表示每个部分的最初高度.有 n 种泥土可用,他们都能覆盖连续 ...

  3. Codeforces 744C. Hongcow Buys a Deck of Cards(状压DP)

    这题的难点在于状态的设计 首先显然是个状压,需要一维表示卡的状态,另一维如果设计成天数,难以知道当前的钱数,没法确定是否能够购买新的卡,如果设计成钱数,会发现状态数过多,空间与时间都无法承受.但是可以 ...

  4. 「CF744C」Hongcow Buys a Deck of Cards「状压 DP」

    题意 你有\(n\)个物品,物品和硬币有\(A\),\(B\)两种类型,假设你有\(M\)个\(A\)物品和\(N\)个\(B\)物品 每一轮你可以选择获得\(A, B\)硬币各\(1\)个,或者(硬 ...

  5. 【BZOJ3312】[Usaco2013 Nov]No Change 状压DP+二分

    [BZOJ3312][Usaco2013 Nov]No Change Description Farmer John is at the market to purchase supplies for ...

  6. HDU-3681-Prison Break(BFS+状压DP+二分)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

  7. [luoguP3092] [USACO13NOV]没有找零No Change(状压DP + 二分)

    传送门 先通过二分预处理出来,每个硬币在每个商品处最多能往后买多少个商品 直接状压DP即可 f[i]就为,所有比状态i少一个硬币j的状态所能达到的最远距离,在加上硬币j在当前位置所能达到的距离,所有的 ...

  8. 2018.12.26 考试(哈希,二分,状压dp)

    T1 传送门 解题思路 发现有一个限制是每个字母都必须相等,那么就可以转化成首尾的差值相等,然后就可以求出\(k-1\)位的差值\(hash\)一下.\(k\)为字符集大小,时间复杂度为\(O(nk) ...

  9. Codeforces 745E Hongcow Buys a Deck of Cards 状压DP / 模拟退火

    题意:现在有n张卡片(n <= 16), 每一轮你可以执行两种操作中的一种.1:获得一张红色令牌和一张蓝色令牌.2:购买一张卡片(如果可以买的话),购买的时候蓝色卡片可以充当蓝色令牌,红色同理, ...

随机推荐

  1. 洛谷 T51922 父子

    题目描述 对于全国各大大学的男生寝室,总是有各种混乱的父子关系. 那么假设现在我们一个男生寝室有不同的 nn 个人,每个人都至多有一个“爸爸”,可以有多个“儿子”,且有且只有一个人没有“爸爸”(毕竟是 ...

  2. mysql根据二进制日志恢复数据/公司事故实战经验

    根据二进制日志恢复 目的:恢复数据,根据二进制日志将数据恢复到今天任意时刻 增量恢复,回滚恢复 如果有备份好的数据,将备份好的数据导入新数据库时,会随着产生二进制日志 先准备一台初始化的数据库 mys ...

  3. C语言程序设计·谭浩强(第四版)第二章课后习题的答案,算法——程序的灵魂

    C语言程序小练习 1.用C语言设计程序算出1-1/2+1/3-14+1/5...+1/99-1/100的值 #include<stdio.h> int main() { ; double ...

  4. oracle监听配置

    在listener.ora文件中指定监听的实例名和修改ip地址: 查看实例名:[localhost$] echo $ORACLE_SID LISTENER = (DESCRIPTION_LIST = ...

  5. (数据科学学习手札05)Python与R数据读入存出方式的总结与比较

    在数据分析的过程中,外部数据的导入和数据的导出是非常关键的部分,而Python和R在这方面大同小异,且针对不同的包或模块,对应着不同的函数来完成这部分功能: Python 1.TXT文件 导入: 以某 ...

  6. jsp中的input

    Input表示Form表单中的一种输入对象,其又随Type类型的不同而分文本输入框,密码输入框,单选/复选框,提交/重置按钮等,下面一一介绍. 1,type=text 输入类型是text,这是我们见的 ...

  7. Python的import导入与时间

    一.模块与包 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量.一般用module_name. ...

  8. 白话HMM系列1——从一个缩略语还原的例子说起

    HMM到底是一个什么样的东西,我想从我研究的一个应用场景开始说起.之所以想重新描述一下我对HMM的理解,是因为上次面试百度糯米的时候,自己没有把HMM在应用上说的很明白,不过糯米的那位郑姓面试官我也是 ...

  9. dom知识总结

    一.dom节点的关系及遍历 element.firstChild; 如果节点为已知节点的第一个子节点就可以使用这个方法.此方法可以递归进行使用 element.firstChild.firstChil ...

  10. [推荐]spring cloud 详解

    http://blog.csdn.net/column/details/15197.html