状压dp(8.8上午)
神马是状态压缩?
就是当普通dp的每一维表示的状态非常少的时候,可以压缩成一维来表示

如果m==8
dp[i][0/1][0/1]......[0/1]
压缩一下
dp[i][s]表示到了第i行,状态是s的方案数

那么状态数是指数级的
有点大.......
考虑每一行的合法状态真的有那么多吗?
考虑只有一行的情况
m: 0 1 2 3 4 5 6 7
f: 1 2 3 5 8 13 21 34
为什么方案数f是斐波那契数列呢?
因为f[i]可以是由f[i-1]再加1个0或者由f[i-2]再加1个01得到

设dp[i][s]为填到第i行,状态为s的状态

.....
说人话:
将s'左移一下,右移一下看一看是否会攻击到s即可
还可以这样判断:(s|s<<1|s>>1)&s'==0的s'是可行的
s是上下攻击,s<<1是在s'左边,s>>1是在s'右边
神奇的位运算

6为什么是枚举子集?
s0每次去掉二进制表示的最后一个1,再和原集进行&操作,就去掉了新的s0的不属于s的部分,同时每次只减去1个1就没有重复
复杂度是
震惊!!!
我们看这个循环,s是枚举有n位的二进制数,它一共有s个1,s0枚举它的子集,子集有
个
总数:
变一变形:
这就是二项式定理啊


看起来n比较小,可以压n的样子
dp[s]表示s这个集合拓扑序的个数
转移:考虑枚举一个点u,加进拓扑序
u满足:1:不在s里面;2:能到达u的点都在s里面
复杂度:
怎么快速判断?
预处理in[u],表示能够到达点u的点组成的集合,当s&in[u]==in[u]时,就是所有能到达u的点都在s里面了

我们可以把每个数拆成q*2x*3y
当q不同的时候,两个数肯定不同,当q相同的时候,就把q提出来。
我们列个表
然后我们可以以行/列/斜着搞dp(就是有i层,不能选相邻的,就转化成了第一个问题)
但是具体选哪个呢?
先考虑列的复杂度:log2n<=17,转移:216
一行一行的:logn<=10:要压到311
当然下一行会少一点,是fib[10](斐波那契第10项)
为什么是fib???
现在问题已经转化成一层内不能选两个相邻的格子的问题了,这个问题的方案数就是fib[这一行的格子数]
我们发现行的复杂度要优一点(虽然依旧玄学),所以我们一行一行的dp
神仙斜着dp
当q>1,等价于q'=1&&n'=n/q。
◦剪枝:对于n/q相同的q,可以避免重复计算来加速。
打过一个表
我们看到最宽的一层第10层宽度只有11,这个范围显然是可以
2^cnt_
NOIP 2016愤怒的小鸟

意思就是选最少的猪的集合,使得这些猪并起来是全集
有用的抛物线:n2个
dp[s]:集合s的猪被消灭最少用的抛物线
枚举包含s最低位的1抛物线t[i],(t[i]代表抛物线i经过的点的集合)
dp[s]=min(dp[s^t[i]]+1)(t[i]&s=t[i]且t[i]包含s的最低位)
这是按照s的最低位来分类,既然我们选了t[i]的点,之前就是dp[s^t[i]],再+1代表用了i这条抛物线
复杂度:2n*n

求出最少的合法的货物集合,使得并起来是原集
和上一个题很像啊
这里我们找出可以被一次运走的货物集合t
再套用上一个题的dp方程
复杂度:3n
枚举子集的复杂度是3n
用f[s]表示s是否能被c1运走,g[s]表示是否能被c2运走
t[s]表示s是否能被两辆车运走(这里是必须用两辆车)
t[s]=|s'f[s']&g[s^s'](s'是s的子集)(|是或运算)
枚举s的子集,看这个子集和s去掉这个子集之后的另一部分能否分别被两辆车运走
分子集的方案有一个满足就够了,所以是用或运算
复杂度3n
bzoj3900

仿佛看见两把刷子

设p[s]表示s集合的麋鹿内部能否交换成合法的麋鹿
排个序,看相邻两个的重量之差是否小于c
如果是,就说明有答案
但如果相邻的两个茸角不属于同一个麋鹿呢?
那最多需要n-1次搞定所有的麋鹿
g[s]表示使s内部消化的最小次数
g[s]≤s内部的人数 -1
那怎么转移呢?
我们不妨先试着把s分成几部分
我们发现s每分出去一部分合法的s',那g[s]至少会-1
why?
举个例子
设s集合原本有t个人,g[s]初始化为t-1
把t分为2部分:t-v,v
那g[v]最坏为v-1,g[t-v]最坏为t-v-1
g[v]+g[t-v]=v-1+t-v-1=t-2
所以每分出去一部分合法的s',g[s]至少会-1
那g[s]=min{g[s']+g[s^s']}(s'∈s)

dp[s][u]:s是三进制数,表示对应位上的点经过几次,u表示现在在哪个点
dp[s][u]=min(dp[s-(1<<i)][i]+dis[i][u])

包肯定是从大到小排序的
f[s]表示装下s的物品,用了多少包
g[s]表示装s的物品,用的最后一个包的剩下的最大空间
转移:看下一个物品能否装在当前的包里面,能则只更新g,否则加一个包,再更新g
dp优化


dp[i][j]表示长度为i,逆序对为j的排列数

我们考虑新来的数插在哪里
原序列:a1,a2,a3....ai-1
放在
我们发现dp[i][j-k]是连续的耶
来个前缀和优化

dp[i][j]=sum[i-1][j]-sum[i-1][j-i]



前缀和:区间的和
单调队列:区间最大值

f[i]表示到第i棵树的最小劳累值

单调队列维护dp值小的,如果dp值相同,选高度要高的

经典的线段覆盖???
显然不是
不过我们还是要按照左端点排序
优化
dp[i][j]表示排完序之后,到了第i条线段,覆盖完前j个位置的方案数
后面*2
前面的累加
发现是区间*2,区间求和
然后就是线段树2的板子

简单的说就是一张纸条要走两次,不能经过重复的点,求经过的点的最大权值
暴力四维dp:

精简一维:
记录步数,第一次的横坐标,第二次的横坐标,然后按照上面的dp即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define ll long long
using namespace std;
inline int read()
{
char ch=getchar();
int x=;bool f=;
while(ch<''||ch>'')
{
if(ch=='-')f=;
ch=getchar();
}
while(ch>=''&&ch<='')
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return f?-x:x;
}
int n,m,ma[][],f[][][];
int main()
{
m=read();n=read();
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
ma[i][j]=read();
for(int k=;k<=n+m-;k++)
{
for(int i=;i<=k;i++)
{
for(int j=;j<=k;j++)
{
int ex1=max(f[k-][i][j],f[k-][i-][j-]);
int ex2=max(f[k-][i-][j],f[k-][i][j-]);
f[k][i][j]=ma[i][k-i+]+ma[j][k-j+]+max(ex1,ex2);
if(i==j)f[k][i][j]-=ma[i][k-i+];
}
}
}
printf("%d",f[n+m-][m][m]);
}
qwq
状压dp(8.8上午)的更多相关文章
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
- HDU 1074 Doing Homework (状压dp)
题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...
- 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP
[BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...
- 【BZOJ1725】[Usaco2006 Nov]Corn Fields牧场的安排 状压DP
[BZOJ1725][Usaco2006 Nov]Corn Fields牧场的安排 Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M< ...
随机推荐
- 洛谷 P5663 加工零件 & [NOIP2019普及组] (奇偶最短路)
传送门 解题思路 很容易想到用最短路来解决这一道问题(题解法),因为两个点之间可以互相无限走,所以如果到某个点的最短路是x,那么x+2,x+4也一定能够达到. 但是如何保证这是正确的呢?比如说到某个点 ...
- [Codeforces 1246B] Power Products (STL+分解质因数)
[Codeforces 1246B] Power Products (STL+分解质因数) 题面 给出一个长度为\(n\)的序列\(a_i\)和常数k,求有多少个数对\((i,j)\)满足\(a_i ...
- pip找不到的安装包
pip install找不到一些python包 可以访问网址,选择python版本自行下载:http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml 清华大学开源 ...
- 使用redis+flask维护动态代理池
在进行网络爬虫时,会经常有封ip的现象.可以使用代理池来进行代理ip的处理. 代理池的要求:多站抓取,异步检测.定时筛选,持续更新.提供接口,易于提取. 代理池架构:获取器,过滤器,代理队列,定时检测 ...
- Python中对 文件 的各种骚操作
Python中对 文件 的各种骚操作 python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Python脚本工作的目录路径: os.getc ...
- 01.AutoMapper 之约定(Conventions)
转载(https://www.jianshu.com/p/d4c472d95da4) 约定(Conventions) 条件对象映射器 条件对象映射器根据源类型和目标类型之间的条件生成新类型映射. ...
- 【学习总结】快速上手Linux玩转典型应用-第6章-linux常用命令讲解
课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. 软件操作命令 2. 服务器硬件资源信息 3. 文件操作命令 4. Linux文本编辑神器vim与其他常用命令 5. 系统用户操作命令 6 ...
- Hive配置日志
1. 重命名hive/conf文件夹下的hive-log4j 2. 修改hive.log.dir参数,如果不修改默认hive.log位于/tmp/{user}下面,一般来说使用在hive目录下自己创建 ...
- 03python面向对象编程之Python中单下划线和双下划线的区别7
通常Python类中会有_和__的方法,是指什么意思呢?如下: 双下划线表示内部不允许访问,一个下划线表示这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽 ...
- Python核心技术与实战——十|面向对象的案例分析
今天通过面向对象来对照一个案例分析一下,主要模拟敏捷开发过程中的迭代开发流程,巩固面向对象的程序设计思想. 我们从一个最简单的搜索做起,一步步的对其进行优化,首先我们要知道一个搜索引擎的构造:搜索器. ...