UVALive 4490 Help Bubu
题目大意:有n本书,高度值域为8,现可以把k本书拿出来再放进去,相邻的、高度相同的书算作一块,最小化块的个数。n=100。
强烈建议大家不要在做完区间DP后做别的DP题:区间DP是整体考虑,而一般DP是考虑以i为末尾,思路完全不同。
难点好像就在于设状态,状态设出来就可以大力转移了。
首先f[i][j],表示到第几本书、用了几次是肯定要设的,但是这样做会缺少很多信息。在转移的时候,我们需要知道最后一位是什么?所以开到f[i][j][k]。
这个就可以DP了。但是答案怎么统计呢?如果最终答案是把几种高度全部扣出来,答案就要比DP值大,但这是我们状态中不能体现的。
看到值域这么小,直接设f[i][j][k][l],表示到第i本书、用了j次取书机会、在书架上的书的集合是k,最后一本书是l的最小块数。
初始化:
f[i+][i][bin[h[i+]]][h[i+]]=;
初始化
转移方程就是讨论一下就可以出来的东西了。
1.当前书取出来:
f[i+][j+][k][l]=min(f[i+][j+][k][l],f[i][j][k][l]);
转移1
2.当前书不取,这时要与最后一位做比较:
f[i+][j][k|bin[h[i+]]][h[i+]]=min(f[i+][j][k|bin[h[i+]]][h[i+]],f[i][j][k][l]+(h[i+]!=l));
转移2
其中bin表示2的多少次方。
在统计答案的时候,要这么统计:
for(int i=;i<=k;++i)
for(int j=;j<bin[];++j)
for(int k=;k<;++k)
if(f[n][i][j][k]!=f[][][][])
Ans=min(Ans,f[n][i][j][k]+num[U^j]);
统计答案
其中num表示二进制下有多少个1。
完整代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <complex>
#include <stack>
#define LL long long int
#define dob double
#define FILE "4490"
using namespace std; const int N = ;
int n,k,bin[],h[N],f[N][N][<<][],t,Ans,num[<<]; inline int gi(){
int x=,res=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')res*=-;ch=getchar();}
while(ch<=''&&ch>='')x=x*+ch-,ch=getchar();
return x*res;
} inline void Min(int &x,int y){
if(x>y)x=y;
} inline void solve(int U=){
for(int i=;i<=n;++i)U|=bin[h[i]=gi()-];
memset(f,/,sizeof(f));Ans=f[][][][];
f[][][bin[h[]]][h[]]=;
for(int i=;i<n;++i){
f[i+][i][bin[h[i+]]][h[i+]]=;
for(int j=;j<=i && j<=k;++j)
for(int k=;k<bin[];++k)
for(int l=;l<;++l)
if(f[i][j][k][l]!=Ans){
Min(f[i+][j+][k][l],f[i][j][k][l]);
Min(f[i+][j][k|bin[h[i+]]][h[i+]],f[i][j][k][l]+(h[i+]!=l));
}
}
for(int i=;i<=k;++i)
for(int j=;j<bin[];++j)
for(int k=;k<;++k)
if(f[n][i][j][k]!=f[][][][])
Min(Ans,f[n][i][j][k]+num[U^j]);
printf("Case %d: %d\n\n",++t,Ans);
} int main()
{
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
bin[]=;for(int i=;i<;++i)bin[i]=bin[i-]*;
for(int i=;i<bin[];++i)num[i]=num[i/]+(i&);
while((n=gi()) && (k=gi()))solve();
fclose(stdin);fclose(stdout);
return ;
}
Help Bubu
UVALive 4490 Help Bubu的更多相关文章
- Help Bubu UVALive - 4490
传送门 题目大意 有n本书,最多k次操作,每次操作可以把一本书拿出来,放到一个位置去,有一个指标较mess度,他是书的高度的段数,连续的书高度一样算一段,现在给你最先开始各个位置上的书的高度,求操作后 ...
- UVALive 4490 压缩DP
转载自http://blog.csdn.net/zstu_zlj/article/details/9903589 没有接触过压缩DP.位运算也不太熟.所以理解了思路还是不懂代码.
- UVA Live Archive 4490 Help Bubu(状压dp)
难点在于状态设计,从左向右一本书一本书的考虑,每本书的决策有两种拿走或者留下, 对于拿走后的书,之后要放回,但是决策过程中不知道到往哪里放, 虽然前面的书的种类确定,可能是往后面放更优,而后面的书的类 ...
- UVALive - 4108 SKYLINE[线段树]
UVALive - 4108 SKYLINE Time Limit: 3000MS 64bit IO Format: %lld & %llu Submit Status uDebug ...
- UVALive - 3942 Remember the Word[树状数组]
UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...
- UVALive - 3942 Remember the Word[Trie DP]
UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...
- 思维 UVALive 3708 Graveyard
题目传送门 /* 题意:本来有n个雕塑,等间距的分布在圆周上,现在多了m个雕塑,问一共要移动多少距离: 思维题:认为一个雕塑不动,视为坐标0,其他点向最近的点移动,四舍五入判断,比例最后乘会10000 ...
- UVALive 6145 Version Controlled IDE(可持久化treap、rope)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- UVALive 6508 Permutation Graphs
Permutation Graphs Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit ...
随机推荐
- 关于RDLC报表打印预览界面显示页码问号的问题
原来在reportview中,vs2010新增了一个属性,pageCountMode,默认的Estimate,提供估算的页数,另外一个属性Actual,提供实际的页数.
- ubuntu debain下好用的编辑器
geany: 轻量级的IDE apt-get install geany 用来写shell脚本和python十分方便.特别写python脚本时,它有丰富的提示和自动补全功能.查看代码也很方便
- #openstack故障处理汇总
##openstack故障处理汇总 排错 openstack pike 部署 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html ############# ...
- Mac中配置nvm
1.安装 nvm curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash 安装成功默认将 ...
- 如果nginx启动失败,错误解决
解决上面问题: /usr/sbin/groupadd -f www /usr/sbin/useradd -g www www 这方法常见出现时反向代理时,ssl的授权用户不存在的情况下出现的:.
- Akka(41): Http:DBTable-rows streaming - 数据库表行交换
在前面一篇讨论里我们介绍了通过http进行文件的交换.因为文件内容是以一堆bytes来表示的,而http消息的数据部分也是byte类型的,所以我们可以直接用Source[ByteString,_]来读 ...
- C#访问C++动态分配的数组指针
项目中遇到C#调用C++算法库的情况,C++内部运算结果返回矩形坐标数组(事先长度未知且不可预计),下面方法适用于访问C++内部分配的任何结构体类型数组.当时想当然的用ref array[]传递参数, ...
- Linux基础-最基础
Linux基础 为了更好的学习知识,开通此博客,以前博客丢了...记录一下知识点,希望能在这里与大家互相学习交流. 20171113 14:00 Linux基础-基本知识 Linux树状文件系统结构 ...
- 【NOIP2012提高组】同余方程
https://www.luogu.org/problem/show?pid=1082 方程可化为ax+by=1. 用扩展欧几里得算法得到ax'+by'=gcd(a,b)的一组解后,可得x=x'/gc ...
- webrtc视频数据render流程