hiho 1044 : 状态压缩
#1044 : 状态压缩·一
描述
小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市——那座城市即将举行美食节!
但是不幸的是,小Hi和小Ho并没有能够买到很好的火车票——他们只能够乘坐最为破旧的火车进行他们的旅程。
不仅如此,因为美食节的吸引,许多人纷纷踏上了和小Hi小Ho一样的旅程,于是有相当多的人遭遇到了和小Hi小Ho一样的情况——这导致这辆车上的人非常非常的多,以至于都没有足够的位置能让每一个人都有地方坐下来。
小Hi和小Ho本着礼让他们的心情——当然还因为本来他们买的就是站票,老老实实的呆在两节车厢的结合处。他们本以为就能够这样安稳抵达目的地,但事与愿违,他们这节车厢的乘务员是一个强迫症,每隔一小会总是要清扫一次卫生,而时值深夜,大家都早已入睡,这种行为总是会惊醒一些人。而一旦相邻的一些乘客被惊醒了大多数的话,就会同乘务员吵起来,弄得大家都睡不好。
将这一切看在眼里的小Hi与小Ho决定利用他们的算法知识,来帮助这个有着强迫症的乘务员——在不与乘客吵起来的前提下尽可能多的清扫垃圾。
小Hi和小Ho所处的车厢可以被抽象成连成一列的N个位置,按顺序分别编号为1..N,每个位置上都有且仅有一名乘客在休息。同时每个位置上都有一些垃圾需要被清理,其中第i个位置的垃圾数量为Wi。乘务员可以选择其中一些位置进行清理,但是值得注意的是,一旦有编号连续的M个位置中有超过Q个的位置都在这一次清理中被选中的话(即这M个位置上的乘客有至少Q+1个被惊醒了),就会发生令人不愉快的口角。而小Hi和小Ho的任务是,计算选择哪些位置进行清理,在不发生口角的情况下,清扫尽可能多的垃圾。
提示一:无论是什么动态规划,都需要一个状态转移方程!
小Hi面对这个问题也是不慌不忙,反倒决定借此机会让小Ho学习一下状态压缩动态规划,于是推了推一旁仍然晕晕乎乎的小Ho,问道:“小Ho,你说这样的问题能否使用动态规划进行解决?”
小Ho思索了一番,在心中默默将这个问题与背包问题进行类比后,道:“我觉得似乎不可以,这个问题和背包问题其实是很类似的,不过背包问题对于选取物品的限制是总重量不能超过一定数额。但在这里却是要求不能够在连续的一段位置中选取太多,如果我仍然以编号从小到大划分阶段,单单以best(i)表示当前已经决定了编号为1..i的位置是否选取的情况下最多可以清扫的垃圾数量的话,因为我不知道之前具体的选取方案,我是没有办法判断当前这个位置能否进行选取的,这便是违反了动态规划状态定义的无后效性!”
小Hi点了点头表示赞同,但随即继续问道:”在背包问题中,正如我们之前经历时所说,我们是通过将best(i)变成best(i, j),增加一个量——当前已经选取物品的总重量j到状态中,从而能够判断当前是否能够继续选取物品,那么在这里,你觉得我们需要添加什么样的量才能够达成我们的目的呢?”
这个问题顿时难倒了小Ho,但他也不是轻易放弃的性格,便拿出纸笔开始写写画画:“正如我之前所说,我不知道之前具体的选取方案,我是肯定没有办法判断当前这个位置能否进行选取的!那么我需要做的事情无非就是在状态中记录之前的选取方法,并且这些记录需要能够让我推算出当前这个位置的垃圾是否能被清扫而不引起口角!”
思路一旦清晰,各种想法便接踵而至,小Ho思索片刻便得出了结论:“如果我将之前每一个位置是否选取的信息都存储下来的话,那么到了决定最后一个位置的时候,最坏情况下我就有2^(N-1)种可能的状态,这个是我所不能接受的,但是我真的需要这么多的信息么?”
“不需要!”小Ho说道:“我只需要知道我之前的M-1个位置中选取了多少个位置就可以了!如果这个数目小于Q,那么我当前就有两种决策方案——选与不选,不然就就只有不选这一种方案。”

小Hi听闻此言,皱了皱眉头,问道:“那你的状态难道就要定义成best(i, j)表示当前已经决定了编号为1..i的位置,并且从i-M+1 ... i-1这M-1个位置中已经选取了j个位置的情况下最多可以清扫的垃圾数量么?”
小Ho刚想称是,却想道小Hi不会无缘无故的问这种问题,于是仔细考虑,顿时发现其中不对:“状态固然是可以了,但是却没有办法进行转移,best(i, j)的下一步肯定是某个best(i+1, k),但是因为无法知晓i-M+1这个位置究竟是否在j个选取的位置中,所以是根本没有办法计算k的!”
“而一旦记录了i-M+1这个位置是否选取了的话,我就还需要记录i-M+2这个位置——因为在best(i+1, k)中它便是(i+1)-M+1的这个位置,以此类推,也就是说我不能够光记录从i-M+1 ... i-1 这M-1个位置中选取了多少个位置,我还要将具体选择了哪些位置都一一记录下来!”小Ho思考道:“那我便只有如此定义状态了——以best(i, p1, p2, p3, ... , pM-1)表示当前已经决定了编号为1..i的位置,并且第(i-j+1)个位置是否选取用pj进行记录(0表示未选取,1表示选取)的情况下最多可以清扫的垃圾数量!”
听完小Ho新的想法,小Hi终于点了点头,但也没放弃继续考校小Ho:“那你准备如何转移状态?”
“这个简单,我只需要统计p1..pM-1之和S——即选取的位置总数,并且根据这个数目进行决策!”小Ho说罢在纸上写出一个公式。

“那具体的计算顺序呢?”小Hi也是将每个步骤都问的详详细细的。
小Ho张口便道:“这个容易,因为每次转移都是从i向i+1进行的,所以我只需要按照i从小到大的顺序进行计算就可以了!”
提示二:好像什么不对劲?状态压缩哪里去了?
在得出结论之后,小Ho便拿出笔记本开始写程序,写着写着便注意到:“这个M是根据输入来的,那么我怎么开数组呢!难道要使用一些动态的方法?这样也未免太过复杂了吧,更何况即使我动态的开了数组,我也没有很好的方法来枚举这些位置,难道要写一大串的条件分支语句?”
思索无奈之下,只能够去询问小Hi,小Hi仿佛早就预料到了这个情况,掏出一张草稿纸来,写下了一个长度为5的01串10101,问道:“你看这是什么?”
“一个2进制串?我算算……等于21?”小Ho耿直的算了出来。
小Hi笑了笑“如果我说这便是M=6的情况下,以第一个01来表示你状态中的p1,第二个01来表示你状态中的p2,并依次类推,那么我是否可以用(i, 21)来表示你的(i, 1, 0, 1, 0, 1)这样一个状态呢?”
小Ho顿时恍然大悟:“是了!既然是01串,那么我就将这M-1个01视作一个二进制数又有何不可!这样一来,我的状态和状态转移方程岂非可以这样定义?”

“是的!这便是所说的状态压缩,它在处理一些变长/变维度的状态时时非常有效的,同时也可以利用位运算来优化代码,方便计算!”小Hi适时的做了总结。
“嗯嗯!我这便去写~”
输入
每个测试点(输入文件)有且仅有一组测试数据。
每组测试数据的第一行为三个正整数N、M和Q,意义如前文所述。
每组测试数据的第二行为N个整数,分别为W1到WN,代表每一个位置上的垃圾数目。
对于100%的数据,满足N<=1000, 2<=M<=10,1<=Q<=M, Wi<=100
输出
对于每组测试数据,输出一个整数Ans,表示在不发生口角的情况下,乘务员最多可以清扫的垃圾数目。
- 样例输入
-
5 2 1
36 9 80 69 85 - 样例输出
-
201
以上解释很详尽
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#define ll __int64
using namespace std;
int n,m,q;
int w[];
int dp[][];
int main()
{
scanf("%d %d %d",&n,&m,&q);
for(int i=;i<=n;i++)
scanf("%d",&w[i]);
for(int i=;i<=n;i++)
{
for(int j=;j<(<<m);j++)
{
int exm=j/+(<<(m-));
int s=exm;
int jishu=;
while(s>)
{
if(s%==)
jishu++;
s/=;
}
if(jishu<=q)
dp[i][exm]=max(dp[i][exm],dp[i-][j]+w[i]);
s=j/;
jishu=;
while(s>)
{
if(s%==)
jishu++;
s/=;
}
if(jishu<=q)
dp[i][j/]=max(dp[i][j/],dp[i-][j]);
}
}
int ans=;
for(int j=;j<(<<m);j++)
ans=max(ans,dp[n][j]);
printf("%d\n",ans);
return ;
}
hiho 1044 : 状态压缩的更多相关文章
- hiho #1044 : 状态压缩·一
描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市——那座城市即将举行美食节! 但是不幸的是,小Hi和小Ho并没有能够买到很好的火车票—— ...
- hihoCoder 1044 : 状态压缩·一 状压dp
思路:状态压缩,dp(i, j)表示考虑前i个数且[i-m+1, i]的选择情况为j.如果要选择当前这个数并且,数位1的个数不超过q,则dp[i+1][nex] = max(dp[i+1][nex], ...
- [hihoCoder] #1044 : 状态压缩·一
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市——那座城市即将 ...
- hihocoder #1044 : 状态压缩·一 状压DP
http://hihocoder.com/problemset/problem/1044 可以看出来每一位的选取只与前m位有关,我们把每个位置起始的前m位选取状态看出01序列,就可以作为一个数字来存储 ...
- hihoCoder #1044 : 状态压缩·一 (清垃圾)
题意: 某车厢有一列座位,共有n个位置,清洁工要在这n个位置上清垃圾,但是不能全部位置都清理,只能选择部分.选择的规则是,连续的m个位置内,不能够清理超过q个,也就是说从第1~m个位置最多可以清q个, ...
- HihoCoder第八周:状态压缩 一
1044 : 状态压缩•一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前 ...
- hihocoder 1334 - Word Construction - [hiho一下第170周][状态压缩+DFS]
题目链接:https://hihocoder.com/problemset/problem/1334 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Given N wo ...
- HihoCoder 1044 垃圾清理 (优化:状态压缩)
状态压缩·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市— ...
- 【HIHOCODER 1044】题目1 : 状态压缩·一
描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市--那座城市即将举行美食节! 但是不幸的是,小Hi和小Ho并没有能够买到很好的火车票-- ...
随机推荐
- 数据库sql优化总结之2-百万级数据库优化方案+案例分析
项目背景 有三张百万级数据表 知识点表(ex_subject_point)9,316条数据 试题表(ex_question_junior)2,159,519条数据 有45个字段 知识点试题关系表(ex ...
- docker部署war包到阿里云
最近买了个阿里云服务器,配置1核2g内存,学习够了.记录下过程. 1,服务器相关,请看下图,云服务器主要配置是安全组和密钥,前者是开放端口,后者可以用于远程连接(比如我windows系统通过putty ...
- phpcms v9手机站不支持组图($pictureurls)的修改
phpcms v9自带的手机门户网站,有时候我们需要用到组图功能$pictureurls,我在做的时候发现,如果$pictureurls中只有一张图片会正常显示,但是如果有两张或两张以上的图片的时候, ...
- 高可用Kubernetes集群-1. 集群环境
参考文档: 部署kubernetes集群1:https://github.com/opsnull/follow-me-install-kubernetes-cluster 部署kubernetes集群 ...
- SPP-net论文总结
SPPNet方法来自<Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition> ,是大神 ...
- jupyter通过notedown使用markdown
0 Problem 最近看了下李沐老师的mxnet教程,在使用jupyter的时候打开教程发现全是markdown源文,没有展示markdown格式的文字. 1 Reason 源代码是用markdow ...
- Linux(Contos7.5)环境搭建之Linux远程登录(一)
1.下载<putty-0.70cn.zip>工具包 2.解压到适合的文件夹下
- Dubbo背景和简介
转载出处 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. 单一应用框架(ORM) 当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本. 缺点:单一的 ...
- List<T>.Distinct()
) }; //使用匿名方法 List<Person> delegateList = personList.Distinct(new Compar ...
- Dijkstra 最短路径算法 秒懂详解
想必大家一定会Floyd了吧,Floyd只要暴力的三个for就可以出来,代码好背,也好理解,但缺点就是时间复杂度高是O(n³). 于是今天就给大家带来一种时间复杂度是O(n²),的算法:Dijkstr ...