[IOI2007]Miners

题目大意:

两个人吃东西,总共有\(3\)种食物,每个人每次吃到食物时可以获得的收益是当前食物和前两次吃的食物中,不同食物的种数。现在给定一个长度为\(n(n\le10^5)\)的食物序列,按顺序每次将这些食物分配给两个人中的一个。问收益总和的最大值。

思路:

\(f[i][j][k][l][m]\)表示分完前\(i\)个吃的,\(A\)最后两个吃了\(i\)和\(j\),\(B\)最后两个吃了\(l\)和\(m\)时的最大收益。

时间复杂度\(\mathcal O(4^4n)\)。

为了防止MLE需要使用滚动数组。

源代码:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
inline int getfood() {
register char ch;
while(!isalpha(ch=getchar()));
if(ch=='M') return 1;
if(ch=='F') return 2;
if(ch=='B') return 3;
return 0;
}
const int N=1e5+1;
int f[2][4][4][4][4];
inline void up(int &x,const int &y) {
x=std::max(x,y);
}
inline int calc(int x,int y,const int &z) {
x=x?:z;
y=y?:z;
if(x==y&&y==z) return 1;
if(x==y&&y!=z) return 2;
if(x==z&&z!=y) return 2;
if(y==z&&x!=y) return 2;
return 3;
}
int main() {
const int n=getint();
for(register int j=0;j<4;j++) {
for(register int k=0;k<4;k++) {
for(register int l=0;l<4;l++) {
for(register int m=0;m<4;m++) {
f[0][j][k][l][m]=INT_MIN;
}
}
}
}
f[0][0][0][0][0]=0;
for(register int i=1;i<=n;i++) {
const bool cur=i&1;
const int x=getfood();
for(register int j=0;j<4;j++) {
for(register int k=0;k<4;k++) {
for(register int l=0;l<4;l++) {
for(register int m=0;m<4;m++) {
f[cur][j][k][l][m]=INT_MIN;
}
}
}
}
for(register int j=0;j<4;j++) {
for(register int k=0;k<4;k++) {
for(register int l=0;l<4;l++) {
for(register int m=0;m<4;m++) {
if(f[cur^1][j][k][l][m]==INT_MIN) continue;
up(f[cur][k][x][l][m],f[cur^1][j][k][l][m]+calc(j,k,x));
up(f[cur][j][k][m][x],f[cur^1][j][k][l][m]+calc(l,m,x));
}
}
}
}
}
int ans=0;
for(register int j=0;j<4;j++) {
for(register int k=0;k<4;k++) {
for(register int l=0;l<4;l++) {
for(register int m=0;m<4;m++) {
up(ans,f[n&1][j][k][l][m]);
}
}
}
}
printf("%d\n",ans);
return 0;
}

[IOI2007]Miners的更多相关文章

  1. [Ioi2007]Miners 矿工配餐(BZOJ1806)

    [Ioi2007]Miners 矿工配餐 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 214  Solved: 128 Description 现有两 ...

  2. BZOJ 1806: [Ioi2007]Miners 矿工配餐( dp )

    dp... ------------------------------------------------------------------------------- #include<cs ...

  3. bzoj1806 [Ioi2007]Miners矿工配餐

    [bzoj1806][Ioi2007]Miners 矿工配餐 2014年7月10日1,7870 Description 现有两个煤矿,每个煤矿都雇用一组矿工.采煤工作很辛苦,所以矿工们需要良好饮食.每 ...

  4. bzoj 1806 [Ioi2007]Miners 矿工配餐(DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1806 [题意] 给定一个权在1..3内的序列,在保持相对位置不变的情况下拆分成两个序列 ...

  5. BZOJ 1806 IOI2007 Miners 矿工配餐 动态规划

    题目大意:将一个123序列拆分为两个子序列.定义每一个数的贡献值为以这个数结尾的长度最大为3的子串中不同数的数量,求贡献值和的最大值 令f[i][a1][a2][b1][b2]为前i个数分成两组,第一 ...

  6. [bzoj1806] [ioi2007]Miners 矿工配餐

    相当于noip前两题难度的ioi题........ 还是挺好想的...算是状压一下?...两个二进制位可以表示三种食物或者没有,所以用四个二进制位表示某个煤矿最近两餐的情况... 先把各种情况加上各种 ...

  7. [IOI2007]Miners 矿工配餐

    link 其实就是一个比较简单的$IOI$题.简单$dp$就行,设$5$维$dp$即可 最后在滚动一下,判一下可行性即可. #include<iostream> #include<c ...

  8. 【动态规划/递推】BZOJ1806[IOI2007]- Miners

    IOI历史上的著名水题,我这种蒟蒻都能写的东西. [思路] 用1.2.3分别代替三种食物,0表示当前矿井没有食物.f[i][a][b][c][d]当前第i个食物,矿1的食物顺序由上至下为a,b:矿2的 ...

  9. 【bzoj1806】[Ioi2007]Miners 矿工配餐 dp

    题目描述 有n个物品,每个都是3种之一.现要将这n个物品分成两个序列,对于每个序列中的每个物品,可以得到 它及它前面相邻的两个物品(不足则取全部)中不同种类的个数 的收益.问最大的总收益. 输入 输入 ...

随机推荐

  1. 2016.07.13-vector<vector<int>>应用2——Two Sum扩展

    收获: vector<vector<int> >res,不能直接用res[j].push_back(number),因为res[j]是空的,没有初始化 可以先定义 vector ...

  2. Python——杂记

    python 最近出错总结: 1.而for..in ..中不要用else if  x in y:     print  else:     print2.def fibs(num): ...     ...

  3. Linux内存初始化【转】

    转自:http://www.cnblogs.com/super-king/p/3291120.html start_kernel -> setup_arch 在这个函数中我们主要看这几个函数. ...

  4. Android Bander设计与实现 - 设计

    Binder Android IPC Linux 内核 驱动 摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC ...

  5. Codeforces Round #504 E. Down or Right

    Codeforces Round #504 E. Down or Right 题目描述:交互题. 有一个\(n \times n\)的方阵,有一些格子是障碍,从\((1, 1)\)出发,只能向右向下走 ...

  6. Java集合之Collection与之子类回顾

    Java学习这么久,打算这几天回顾下java的基本知识点,首先是集合. 一.常用集合类关系图 Collection |___List 有序,可重复 |___ArrayList  底层数据结构是数组,增 ...

  7. Windows平台的rop exp编写

    摘抄自看雪 Windows的ROP与Linux的ROP并不相同,其实Linux下的应该叫做是ret2libc等等.Windows的ROP有明确的执行目标,比如开辟可执行内存然后拷贝shellcode, ...

  8. 一步一步学习IdentityServer3 (6)

    上一个章节提到了数据持久化 下面说一说自定义登录界面,Idr3提供了很多服务接口,其中一个就是 ViewService,我们只需要去注册 IViewService 这个接口的实现 提供了一个泛型视图服 ...

  9. 【51nod】1312 最大异或和

    题解 很显然我们求出一组线性基来,如果有M个基,那么可以构造N - M + 1个最大异或值 而对于线性基中的元素,除了最大的元素,我们用最大异或值异或掉每个元素累加进答案 而不是把线性基中的元素处理成 ...

  10. 2018 ACM-ICPC, Syrian Collegiate Programming Contest F - Pretests SOS dp

    #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk mak ...