【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个数分成两组,第一 ...
随机推荐
- web3.js_1.x.x--API(一)event/Constant/deploy/options
/* 事件是使用EVM日志内置功能的方便工具,在DAPP的接口中,它可以反过来调用Javascript的监听事件的回调. 事件在合约中可被继承.当被调用时,会触发参数存储到交易的日志中(一种区块链上的 ...
- Volatile的详解
volatile关键字修饰的共享变量主要有两个特点:1.保证了不同线程访问的内存可见性 2.禁止重排序 在说内存可见性和有序性之前,我们有必要看一下Java的内存模型(注意和JVM内存模型的区分 ...
- 网络编程之socket的运用
一,socket用法 socket是什么 ? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐 ...
- Vijos 纸牌
题目网址 https://vijos.org/d/Randle/p/5a0011e1d3d8a10a532d6d71 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真 ...
- java8lambda表达式初识
一.函数式接口 只有一个 抽象方法 的 接口 叫函数式接口 /** * @auther hhh * @date 2018/12/24 22:20 * @description 函数式接口:只有 一个 ...
- python2.7入门---列表(List)
序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推.Python有6个序列的内置类型,但最常见的是列表和元组. ...
- python2.7练习小例子(十七)
17):题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字.例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制. 程序分析: ...
- MVC5使用单选按钮与下拉框【转】
某人认为下拉列表的呈现形式不如单选按钮漂亮,我只好去测试一下单选按钮与下拉框了.测试代码如下: 1.model类Blog.cs(类型使用枚举类型,自动生成的视图会以下拉列表形式显示): using S ...
- Java日志(一):log4j与.properties配置文件
日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录,在Apache网站jakarta.apache.org/log4j可以免费下载到Log4j ...
- Jmeter使用时异常问题解决
1.执行jmeter请求时,响应数据中出现乱码异常(如图) 解决方案: 打开E:\apache-jmeter-4\bin\jmeter.properries(jmeter安装目录),查找到语句行:#s ...