[JZOJ3521]道路覆盖--状压DP
题目链接
略略略
分析
首先一看到使得最低的高度最高就想到了二分,于是就转化成了一个是否可行的问题
发现这个\(k\)都很小,考虑使用状态压缩DP
但是我一开始发现似乎并不好设计状态...如果这个\(k\)表示前\(k\)个方块的状态有没有开始涂似乎不好转移
看了solution发现我还是\(Too Young Too Simple\)
我们用对于第\(i\)块,对它决策有影响的只有它前面的\(i-k+1\)块的状态,于是我们只需要用一个\(k\)位二进制串表示状态来从\(i\)递推到\(i+1\).对于块\(p\)二进制串的第\(i\)位(0位开始)表示第\(p-(k-i-1)\)块的状态
\(f[i][s]\)表示已经从前往后决策完第\(i\)块,\(i-k+1\)到\(i\)的状态为\(s\)的最小代价,这些状态保证都是合法的(即所有的高度等于等于二分值)
这时候从\(i\)递推到\(i+1\)的话我们需要知道之前\(i+1\)之前\(k\)块能累高\(i+1\)块多少高度,这直接扫一遍就好了
如果之前累加的高度\(dta\)+\(h[i+1]\)大于等于二分的高度,那么我们可以不选涂第\(i+1\)块
\(f[i+1][s>>1]=min(f[i+1][s>>1],f[i][s])\),这时候第\(k-1\)位为0表示\(i+1\)位没涂
如果\(dta+h[i+1]+e[i+1]\)大于等于二分值,那么我们就可以涂
\(f[i+1][s>>1|(1<<(k-1))]=min(f[i+1][s>>1|(1<<(k-1))],f[i][s]+c[i+1])\)
意义和第一个类似表示\(i+1\)位涂的状态
最后判断是否有状态\(f[n][s]<=m\)就好了
感觉这题还是挺不错的,通过考虑那些状态会影响决策来减小决策空间,表示状态的方法也比较独特(可能是我太菜做的题少)
同时从大佬代码中学到了一个优化就是可行性剪枝,对于\(f[i][s]\)已经大于等于\(m\)的我们直接不管
代码
/*
code by RyeCatcher
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <utility>
#include <queue>
#include <vector>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <iostream>
#define DEBUG freopen("dat.in","r",stdin);freopen("wa.out","w",stdout);
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define ri register int
#define ll long long
#define ull unsigned long long
#define SIZE 1<<22
using std::min;
using std::max;
using std::priority_queue;
using std::queue;
using std::vector;
using std::pair;
using namespace __gnu_pbds;
inline char gc(){
static char buf[SIZE],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;
while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
}
const int maxn=1005;
const int inf=0x7fffffff-1926817;
int f[maxn][1<<11];
int S,n,m,k;
int h[maxn],c[maxn],e[maxn];
inline bool chk(int qwq){
for(ri i=0;i<=n;i++)for(ri j=0;j<S;j++)f[i][j]=inf;
f[0][0]=0;
int num=0;
for(ri o=0;o<n;o++){
for(ri i=0;i<S;i++){
if(f[o][i]>m)continue;//优化
num=0;
for(ri j=1;j<k;j++){
if(o-(k-j)+1<=0)continue;
if(i&(1<<j))num+=e[o-(k-j)+1];
}
if(num+h[o+1]>=qwq){
f[o+1][i>>1]=min(f[o+1][i>>1],f[o][i]);
}
if(num+h[o+1]+e[o+1]>=qwq){
f[o+1][i>>1|(1<<(k-1))]=min(f[o+1][i>>1|(1<<(k-1))],f[o][i]+c[o+1]);
}
}
}
for(ri j=0;j<S;j++)if(f[n][j]<=m)return 1;
return 0;
}
int main(){
int ans=0;
FO(cover)
read(n),read(m),read(k);
for(ri i=1;i<=n;i++){
read(h[i]),read(e[i]),read(c[i]);
}
S=1<<k;
int mid,L=0,R=1e6+5;
while(L<=R){
mid=(L+R)>>1;
if(chk(mid))ans=mid,L=mid+1;
else R=mid-1;
}
printf("%d\n",ans);
return 0;
}
[JZOJ3521]道路覆盖--状压DP的更多相关文章
- POJ2411骨牌覆盖——状压dp
题目:http://poj.org/problem?id=2411 状压dp.注意一下代码中标记的地方. #include<iostream> #include<cstdio> ...
- bzoj3195: [Jxoi2012]奇怪的道路(状压dp)
Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期有n座城市,编号为1..n.m条道路连接在这些城市之间,每 ...
- 棋盘覆盖 状压DP+矩阵快速幂
题意:有一个m 行n 列的矩形方格棋盘,1 < = m< = 5,1=< n< =10^9,用1*2 的骨牌(可横放或竖放)完全覆盖,骨牌不能重叠,有多少种不同的覆盖的方法.你 ...
- [Jxoi2012]奇怪的道路 BZOJ3195 状压DP
分析: k很小,可以状压. f[S][i]表示状态S表示在i之前k+1个中点的边数奇偶情况 之后转移的时候,S的最后一位不能为1 附上代码: #include <cstdio> #incl ...
- BZOJ3195: [Jxoi2012]奇怪的道路【状压DP】
Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期有n座城市,编号为1..n.m条道路连接在这些城市之间,每 ...
- BZOJ 3195: [Jxoi2012]奇怪的道路(状压dp)
f[i][j][s]表示当前处理第i个点,前i-1个点已连j条边,第i个点开始k个点的奇偶性状态. #include<cstring>#include<algorithm>#i ...
- 2018.10.24 bzoj3195: [Jxoi2012]奇怪的道路(状压dp)
传送门 f[i][j][k]f[i][j][k]f[i][j][k]表示前iii个点连了jjj条边,第i−K+1i-K+1i−K+1~iii个点连边数的奇偶性为kkk时的方案数. 转移规定只能从后向前 ...
- 【BZOJ3195】[Jxoi2012]奇怪的道路 状压DP
[BZOJ3195][Jxoi2012]奇怪的道路 Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期有n座 ...
- 【BZOJ4560】[JLoi2016]字符串覆盖 KMP+状压DP
[BZOJ4560][JLoi2016]字符串覆盖 Description 字符串A有N个子串B1,B2,…,Bn.如果将这n个子串分别放在恰好一个它在A中出现的位置上(子串之间可以重叠)这样A中的若 ...
随机推荐
- ArcGIS Python 唯一值专题
import arcpy mxd = arcpy.mapping.MapDocument("current") lyr = arcpy.mapping.ListLayers(mxd ...
- Django module
1,模型定义 models.py的例子: class Author(models.Model): name=models.CharField(max_length=20) class Book(mod ...
- linux安装后需要进行的一些基本设置
修改网络: 在终端中输入:vi /etc/sysconfig/network-scripts/ifcfg-ens33 然后重启网络服务:systemctl restart network.servic ...
- Java FTP客户端开源类库 edtFTPj
edtFTPj/Free是免费的流行的Java FTP库,全球公司依靠edtFTPj /Free 为它们的Java应用程序添加FTP客户端功能. (收费的支持SFTP.FTPS的edtFTPj/PRO ...
- QPixmap QImage 相互转化
QPainter p(this); QPixmap pixmap; pixmap.load("E:\\参考文件\\image\\1.jpg"); //QPixmap->QIm ...
- pycharm建立第一个django工程-----windows中
pycharm建立第一个django工程 系统:win764 ip: 192.168.0.100 安装django pip install django 左上角建立一个名为Firstdjango工程 ...
- matlab boundaries和fchcode函数无法执行的解决办法 未定义与 'double' 类型的输入参数相对应的函数 'boundaries'
在测试代码时发现,自己的matlab无法执行Freeman链码函数: boundaries和fchcode函数都无法正常运行: 需要在自己的工作目录中添加如下函数: boundaries fchc ...
- Java实现汉诺塔移动,只需传一个int值(汉诺塔的阶)
public class HNT { public static void main(String[] args) { HNT a1 = new HNT(); a1.lToR(10); //给汉诺塔a ...
- Cracking the coding interview目录及资料收集
前言 <Cracking the coding interview>是一本被许多人极力推荐的程序员面试书籍, 详情可见:http://www.careercup.com/book. 第六版 ...
- Reactor系列(七)flatMap映射
#java##reactor##flatMap# 视频讲解: https://www.bilibili.com/video/av79582009/ FluxMonoTestCase.java pack ...