这个题我们可以想象成_---___-----__的一个水柱它具有一遍优一遍行的性质因此可以用来二分最小值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. python生成器详解

    1. 生成器 利用迭代器(迭代器详解python迭代器详解),我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成.但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记 ...

  2. Leecode刷题之旅-C语言/python-26.删除数组中的重复项

    /* * @lc app=leetcode.cn id=26 lang=c * * [26] 删除排序数组中的重复项 * * https://leetcode-cn.com/problems/remo ...

  3. Linux中程序的编译和链接过程

    1.从源码到可执行程序的步骤:预编译.编译.链接.strip 预编译:预编译器执行.譬如C中的宏定义就是由预编译器处理,注释等也是由预编译器处理的. 编译: 编译器来执行.把源码.c .S编程机器码. ...

  4. 「LibreOJ#515」贪心只能过样例 (暴力+bitset)

    可以发现,答案最大值只有106,于是想到用暴力维护 可以用bitset合并方案可以优化复杂度, Code #include <cstdio> #include <bitset> ...

  5. DDL失败案例

    问题描述 今天对线上某个业务的大表120G进行重建表操作时遇到报错,该表有个比较显著的特征是*写入量比较大,每天写入加更新的频率在数千万级别.大致的环境 1 版本:Percona 5.6.24 2 操 ...

  6. HTC Vive小场地与大场景空间的解决方案

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/52780621 作者:car ...

  7. P2384洛谷 最短路

    题目描述 给定n个点的带权有向图,求从1到n的路径中边权之积最小的简单路径. 输入输出格式 输入格式: 第一行读入两个整数n,m,表示共n个点m条边. 接下来m行,每行三个正整数x,y,z,表示点x到 ...

  8. 拉普拉斯矩阵(Laplacian Matrix) 及半正定性证明

    摘自 https://blog.csdn.net/beiyangdashu/article/details/49300479 和 https://en.wikipedia.org/wiki/Lapla ...

  9. [leetcode-648-Replace Words]

    In English, we have a concept called root, which can be followed by some other words to form another ...

  10. POJ 3177 Redundant Paths & POJ 3352 Road Construction(双连通分量)

    Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numb ...