题目大意:有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+1][i][bin[h[i+1]]][h[i+1]]=1;

初始化

  转移方程就是讨论一下就可以出来的东西了。

  1.当前书取出来:

f[i+1][j+1][k][l]=min(f[i+1][j+1][k][l],f[i][j][k][l]);

转移1

  2.当前书不取,这时要与最后一位做比较:

f[i+1][j][k|bin[h[i+1]]][h[i+1]]=min(f[i+1][j][k|bin[h[i+1]]][h[i+1]],f[i][j][k][l]+(h[i+1]!=l));

转移2

  其中bin表示2的多少次方。

  在统计答案的时候,要这么统计:

for(int i=0;i<=k;++i)for(int j=0;j<bin[8];++j)for(int k=0;k<8;++k)if(f[n][i][j][k]!=f[0][0][0][0])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 = 110;
int n,k,bin[10],h[N],f[N][N][1<<8][9],t,Ans,num[1<<8];inline int gi(){int x=0,res=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return x*res;
}inline void Min(int &x,int y){if(x>y)x=y;
}inline void solve(int U=0){for(int i=1;i<=n;++i)U|=bin[h[i]=gi()-25];memset(f,127/3,sizeof(f));Ans=f[0][0][0][0];f[1][0][bin[h[1]]][h[1]]=1;for(int i=1;i<n;++i){f[i+1][i][bin[h[i+1]]][h[i+1]]=1;for(int j=0;j<=i && j<=k;++j)for(int k=0;k<bin[8];++k)for(int l=0;l<8;++l)if(f[i][j][k][l]!=Ans){Min(f[i+1][j+1][k][l],f[i][j][k][l]);Min(f[i+1][j][k|bin[h[i+1]]][h[i+1]],f[i][j][k][l]+(h[i+1]!=l));}}for(int i=0;i<=k;++i)for(int j=0;j<bin[8];++j)for(int k=0;k<8;++k)if(f[n][i][j][k]!=f[0][0][0][0])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[0]=1;for(int i=1;i<10;++i)bin[i]=bin[i-1]*2;for(int i=1;i<bin[8];++i)num[i]=num[i/2]+(i&1);while((n=gi()) && (k=gi()))solve();fclose(stdin);fclose(stdout);return 0;
}

Help Bubu

转载于:https://www.cnblogs.com/fenghaoran/p/7672813.html

UVALive 4490 Help Bubu相关推荐

  1. uvaLive 4490 Help Bubu 帮助布布 等价转化+DP

    等价转换: 从有n本书的书堆里面抽取k本书,再插入书堆里面,计算书的杂乱度 等价于 向空的书架上按给出的顺序放上n本书,再从中抽取k本书,然后插入书堆里面,计算书的杂乱度 等价于 向空的书架上按给出的 ...

  2. DP UVALive 6506 Padovan Sequence

    题目传送门 /*题意:两行数字,相邻列一上一下,或者隔一列两行都可以,从左到右选择数字使和最大DP:状态转移方程:dp[i][j] = max (dp[i][j], dp[1-i][j-1] + a[ ...

  3. The UVALIVE 7716 二维区间第k小

    The UVALIVE 7716 二维区间第k小 /** 题意:给一个n * n的矩阵,有q个查询每次查询r,c,s,k表示已(r,c)为右上角 大小为s的正方形中 第k小的元素n <= 250 ...

  4. 2020年球云计算市值或将达4490亿欧元

    据相关调查数据显示,由于云服务采用普及率的提高,2020年累计总收入预计达到4490亿欧元,达到欧盟28个成员国的国内生产总值. 根据在2014年12月到2016年4月间进行的调查报告显示,2015年 ...

  5. UVALive 8513 lovers 2017 西安区域赛 B 贪心+multiset

    UVALive 8513 有2种人,每个人有自己的权值$A_i$ $B_i$ 当$A_i + B_i >=K$时 两个人可以配对 问最多多少人可以配对 解法 : 把$/{ A_i /}$ 排序 ...

  6. 训练指南 UVALive - 3713 (2-SAT)

    layout: post title: 训练指南 UVALive - 3713 (2-SAT) author: "luowentaoaa" catalog: true mathja ...

  7. 逆序数 UVALive 6508 Permutation Graphs

    题目传送门 1 /* 2 题意:给了两行的数字,相同的数字连线,问中间交点的个数 3 逆序数:第一行保存每个数字的位置,第二行保存该数字在第一行的位置,接下来就是对它求逆序数 4 用归并排序或线段树求 ...

  8. Infinite Fraction Path UVALive - 8207

    Infinite Fraction Path UVALive - 8207 题意: 给你n个数,每个数在0到9之间,每个数的下标一次是0~n-1,然后他所能走到的数为(i^2+1)%n,i为他本身的下 ...

  9. F - Heron and His Triangle UVALive - 8206

    F - Heron and His Triangle UVALive - 8206 题意: 给你应该n,然后求一个最小的t,问长度为t-1,t,t+1所组成的三角形的面积为整数,t>=n 题解: ...

  10. Tree UVALive - 8212

    Tree UVALive - 8212 题意: 有n个点,k个颜色,每个点都要被染色,相同颜色之间的边算是被该颜色覆盖,问有多少边被所有颜色覆盖 题解: 题目给的是无根树,我们可以将1默认为根然后求所 ...

最新文章

  1. Effective STL 为包含指针的关联容器指定比较类型
  2. 收藏功能_微信强大的收藏功能,你们用了吗?
  3. python判断集合为空
  4. 中国AI创新者论坛将于3月21日在清华大学举办
  5. Angular self study 3 - data binding
  6. flink 检查点_Flink检查点和恢复
  7. go mongodb排序查询_《MongoDB》day two
  8. oracle ado6,c# ado 连接数据库 六步曲
  9. 如何用SQL语句查询Excel数据
  10. php 每日一句名人名言,每日一句人生格言
  11. PAT (Advanced Level) Practice 1001 A+B Format (20分)
  12. EF批量添加数据BulkInsert
  13. 【图像检测-缺陷检测】基于计算机视觉实现液晶显示器表面缺陷检测含Matlab源码
  14. Google可能将退出中国市场
  15. S3C2440移植uboot之支持NAND启动
  16. setpositivebutton
  17. C语言数组比较相等memcmp,使用memcmp比较两个变量结果一定吗?
  18. 视频号拍摄技巧和制作方法有哪些?
  19. 云服务器就是虚拟机,云服务器就是一个虚拟机吗
  20. Citrix联机插件配置管理器:找不到满足所有锁定要求的值

热门文章

  1. 4刀最多切割一个正方体为多少部分
  2. 太阳时角、太阳高度角、天顶角、太阳方位角和剖面角计算的Python程序
  3. 机器学习笔记 - 学习使用TensorFlow和张量处理单元 (TPU) 构建图像分类模型
  4. linux 查看内网IP和外网IP
  5. IcedTea6 1.7.3
  6. 你相信吗?这些照片其实并没有被PS_-Chaz-_新浪博客
  7. 只有1kb的清理软件_教您清理1kb快捷方式病毒
  8. Java操作Oracle数据库——ARRAY TABLE类型批量数据处理区别比较
  9. 电脑开机加速,一下子就提升了20几秒
  10. Unity小游戏教程系列 | 创建小型太空射击游戏(4)