【bzoj1806】[Ioi2007]Miners 矿工配餐 dp
题目描述
有n个物品,每个都是3种之一。现要将这n个物品分成两个序列,对于每个序列中的每个物品,可以得到 它及它前面相邻的两个物品(不足则取全部)中不同种类的个数 的收益。问最大的总收益。
输入
输入的第一行包含一个整数N (1 ≤ N ≤ 100 000), 表示食品车的数目。 第二行包含一个由N个字符组成的字符串,按照配送顺序依次表示食品车配送的食品的类型。每个字符是以下三个大写字母之一:'M' (表示肉类), 'F' (表示鱼类) 或 'B' (表示面包)。
输出
输出一个整数,表示最大的总产煤量。 评分 在45分的测试数据中,食品车的数目至多为20
样例输入
6
MBMFFB
样例输出
12
题解
dp
设$f[i][j][k][l][m]$表示前$i$个物品,第一个序列的最后一个是$j$,第一个序列的倒数第二个是$k$,第二个序列的最后一个是$l$,第二个序列的倒数第二个是$m$的最大总收益(物品不存在则为0)。
那么每次只需要讨论当前物品放到哪个序列即可,状态转移方程详见代码。
由于空间不足,所以需要滚动数组。
时间复杂度$O(n*4^4)$
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[2][4][4][4][4] , v[100010] , cnt[4];
char s[100010];
inline void gmax(int &x , const int y)
{
x < y ? x = y : 0;
}
inline int calc(int a , int b , int c)
{
cnt[1] = cnt[2] = cnt[3] = 0 , cnt[a] = 1 , cnt[b] = 1 , cnt[c] = 1;
return cnt[1] + cnt[2] + cnt[3];
}
int main()
{
int n , d , i , j , k , l , m , ans = 0;
scanf("%d%s" , &n , s + 1);
for(i = 1 ; i <= n ; i ++ ) v[i] = (s[i] == 'M' ? 1 : s[i] == 'F' ? 2 : 3);
memset(f , 0xc0 , sizeof(f)) , f[0][0][0][0][0] = 0;
for(d = i = 1 ; i <= n ; i ++ , d ^= 1)
for(j = 0 ; j <= 3 ; j ++ )
for(k = 0 ; k <= 3 ; k ++ )
for(l = 0 ; l <= 3 ; l ++ )
for(m = 0 ; m <= 3 ; m ++ )
gmax(f[d][v[i]][j][l][m] , f[d ^ 1][j][k][l][m] + calc(v[i] , j , k)) , gmax(f[d][j][k][v[i]][l] , f[d ^ 1][j][k][l][m] + calc(v[i] , l , m));
for(i = 0 ; i <= 3 ; i ++ )
for(j = 0 ; j <= 3 ; j ++ )
for(k = 0 ; k <= 3 ; k ++ )
for(l = 0 ; l <= 3 ; l ++ )
gmax(ans , f[n & 1][i][j][k][l]);
printf("%d\n" , ans);
return 0;
}
【bzoj1806】[Ioi2007]Miners 矿工配餐 dp的更多相关文章
- bzoj1806 [Ioi2007]Miners矿工配餐
[bzoj1806][Ioi2007]Miners 矿工配餐 2014年7月10日1,7870 Description 现有两个煤矿,每个煤矿都雇用一组矿工.采煤工作很辛苦,所以矿工们需要良好饮食.每 ...
- BZOJ 1806: [Ioi2007]Miners 矿工配餐( dp )
dp... ------------------------------------------------------------------------------- #include<cs ...
- [bzoj1806] [ioi2007]Miners 矿工配餐
相当于noip前两题难度的ioi题........ 还是挺好想的...算是状压一下?...两个二进制位可以表示三种食物或者没有,所以用四个二进制位表示某个煤矿最近两餐的情况... 先把各种情况加上各种 ...
- [Ioi2007]Miners 矿工配餐(BZOJ1806)
[Ioi2007]Miners 矿工配餐 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 214 Solved: 128 Description 现有两 ...
- bzoj 1806 [Ioi2007]Miners 矿工配餐(DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1806 [题意] 给定一个权在1..3内的序列,在保持相对位置不变的情况下拆分成两个序列 ...
- BZOJ 1806: [Ioi2007]Miners 矿工配餐
ime Limit: 10 Sec Memory Limit: 64 MBSubmit: 910 Solved: 559[Submit][Status][Discuss] Description ...
- [IOI2007]Miners 矿工配餐
link 其实就是一个比较简单的$IOI$题.简单$dp$就行,设$5$维$dp$即可 最后在滚动一下,判一下可行性即可. #include<iostream> #include<c ...
- 洛谷 P4401 [IOI2007]Miners 矿工配餐
题意简述 有两个矿洞,已知食物的种类(≤3)和顺序,将他们送往任一矿洞, 若一个矿洞3次食物相同,贡献1:若有2种不同食物,贡献2:若有3种不同食物,贡献3 求最大贡献 题解思路 food[i] 为当 ...
- BZOJ 1806 IOI2007 Miners 矿工配餐 动态规划
题目大意:将一个123序列拆分为两个子序列.定义每一个数的贡献值为以这个数结尾的长度最大为3的子串中不同数的数量,求贡献值和的最大值 令f[i][a1][a2][b1][b2]为前i个数分成两组,第一 ...
随机推荐
- 搭建两个节点的大数据集群-1.hdfs集群
0.规划 两个节点: ip 部署的程序 备注 192.168.56.2/bigdata.lzf namenode,datanode,NodeManager,hive,presto,mysql, ...
- 使用公共的存储过程实现repeater的分页
当一个项目repeater分页多的时候使用公共的存储过程实现分页,是不错的选择 ALTER PROC [dbo].[P_Common_proc] -- 通用分页存储过程 @TableName varc ...
- 2017年PHP程序员未来路在何方?(转载)
PHP 从诞生到现在已经有 20 多年历史,从 Web 时代兴起到移动互联网退潮,互联网领域各种编程语言和技术层出不穷, Node.js . GO . Python 不断地在挑战 PHP 的地位.这些 ...
- 搞笑入群二维码在线生成源码 php图片合成并添加文字水印
在凤凰网看到一篇文章:微信群二维码也能“整人”,99%的好友会中招!感觉挺好玩,所以自己也想做一个! 冷静分析
- weui-switch开关控件,表单提交后如何取值
最近在学习weui这个框架,做了一些小的试验,发现weui-switch控件直接提交不能获取到表单信息,在segmentfault上发现也有人提了这个问题,有人说可以设置一个隐含标签来捕获开关的状态, ...
- centOS下更新yum源
CentOS下更新yum源 1.使用如下命令,备份/etc/yum.repos.d/CentOS-Base.repo. cp /etc/yum.repos.d/CentOS-Base.repo /et ...
- ruby中将数字转化为字符串格式时差
工作中有时候会碰到需要把数值展示成比较直观的时间差格式,divmod方法很适合做这个操作. divmod #输出商和余数的数组 60.divmod(50) #=> [1, 10 ...
- 网站安全检测 漏洞检测 对thinkphp通杀漏洞利用与修复建议
thinkphp在国内来说,很多站长以及平台都在使用这套开源的系统来建站,为什么会这么深受大家的喜欢,第一开源,便捷,高效,生成静态化html,第二框架性的易于开发php架构,很多第三方的插件以及第三 ...
- hack游戏攻略(黑吧安全吧的黑客闯关游戏)古墓探秘
2019.2.11 这个是找到的一个黑客游戏,就是一关一关,挺像ctf的,玩玩也挺有意思,还能涨知识. 地址:http://hkyx.myhack58.com/ 入口: 入口就是这样的.提示是 图内有 ...
- shell重温---基础篇(流程控制&if判断&for&while&循环操作)
和Java.PHP等语言不一样,sh的流程控制不可为空,如(以下为PHP流程控制写法): <?php if (isset($_GET["q"])) { search( ...