先从样例模拟清楚题意:

...最后模拟可以得到答案4

题意:求前n个岛中最多的绿岛数,根据罗盘预测结果知道实际上绿岛数

dp做法

由于dp问题的使用条件是1.最优子结构 2.不具有后效性

本题是一个线性递推的过程,存在最优子结构

由于处于某一点时,当前的状态(什么颜色) 是会影响到后面两座岛屿的

所以我们可以多开几维,因为颜色就只有三种,可以枚举出来

最后的时间复杂度是O(n*3^4)

原问题:考虑前n个岛屿后,最多的绿岛数

子问题:考虑前i个岛屿,且i为a岛,i-1为b岛,i-2为c岛时的最多绿岛数

状态表示:dp[i][a1][a2][a3]

集合:所有考虑前i个岛屿,且i为a岛,i-1为b岛,i-2为c岛的所有集合

属性:max

可以发现

  • 罗盘预测为green的所有集合都满足 g>r
  • 罗盘预测为red的所有集合都满足g<r
  • 罗盘预测为black的所有都满足g==r

根据划分依据:最后一个不同点,可以将集合划分为不重不漏的三个子集

  • 当前罗盘为a  且  三个岛中g>r
  • 当前罗盘为b  且  三个岛中g<r
  • 当前罗盘为c  且  三个岛中g==r

边界:负无穷   (不满足预测的方案,他的值应该为负无穷或-1,表示不满足预测)

初始化:dp[3][..][..][..]=对应的绿岛数

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1e5+10;
int dp[N][4][4][4];
int main()
{int n;cin>>n;string s;cin>>s;s=" "+s;memset(dp,-1,sizeof dp);//预处理前3个岛屿for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)for(int k=1;k<=3;k++){int g=0,r=0,b=0;if(i==1) g++;if(i==2) r++;if(i==3) b++;if(j==1) g++;if(j==2) r++;if(j==3) b++;if(k==1) g++;if(k==2) r++;if(k==3) b++;if(g<r&&s[3]=='R') dp[3][i][j][k]=g;if(g>r&&s[3]=='G') dp[3][i][j][k]=g;if(g==r&&s[3]=='B') dp[3][i][j][k]=g;}for(int i=4;i<=n;i++)for(int a=1;a<=3;a++)for(int b=1;b<=3;b++)for(int c=1;c<=3;c++){int g=0,r=0,bl=0;if(a==1) g++;if(a==2) r++;if(a==3) bl++;if(b==1) g++;if(b==2) r++;if(b==3) bl++;if(c==1) g++;if(c==2) r++;if(c==3) bl++;for(int l=1;l<=3;l++){if(dp[i-1][b][c][l]==-1) continue;//这句一定要加,如果这个方案下前面所有岛屿都不满足预测,即使当前岛屿满足预测,也是不符合条件的,所以应该让他直接跳过,不能用来更新
//也可以定义dp数组初值负无穷,res<0就代表无解if(g<r&&s[i]=='R')dp[i][a][b][c]=max(dp[i][a][b][c],dp[i-1][b][c][l]+(a==1));if(g>r&&s[i]=='G')dp[i][a][b][c]=max(dp[i][a][b][c],dp[i-1][b][c][l]+(a==1));if(g==r&&s[i]=='B')dp[i][a][b][c]=max(dp[i][a][b][c],dp[i-1][b][c][l]+(a==1));}}int res=-1;for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)for(int k=1;k<=3;k++)res=max(res,dp[n][i][j][k]);cout<<res;return 0;
}

优化

可以进一步对于状态进行优化

我们发现当前点会考虑前面两个点 i-1 i-2  而 i-1 会考虑前面两个点 i-2 i-3...

而其实i-3对于在第i点的状态转移是没有任何帮助的,根据上面的状态转移我们也发现了

所以其实可以把状态表示方程进一步的优化,优化成为三维的

原问题:考虑前n个岛屿,其中最多的绿岛数

子问题:考虑前i个岛屿,其中i为a岛,i-1为b岛的最大绿岛数

状态转移:根据定义,我们只需要记录两座岛的颜色,在状态转移的时候,确保前面两座岛的颜色都被考虑进入(i-1,i-2颜色都被枚举到),就可以达到不重不漏,而i-3是没有用的,所以可以舍弃

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1e5+10;
int dp[N][4][4];
int main()
{int n;cin>>n;string s;cin>>s;s=" "+s;memset(dp,-0x3f,sizeof dp);for(int i=1;i<=3;i++)for(int j=1;j<=3;j++){int g=(i==1)+(j==1),r=(i==2)+(j==2);dp[2][i][j]=g;}for(int i=3;i<=n;i++)for(int a=1;a<=3;a++)for(int b=1;b<=3;b++)for(int c=1;c<=3;c++){int g=(a==1)+(b==1)+(c==1);int r=(a==2)+(b==2)+(c==2);if(g<r&&s[i]=='R')dp[i][a][b]=max(dp[i][a][b],dp[i-1][b][c]+(a==1));if(g>r&&s[i]=='G')dp[i][a][b]=max(dp[i][a][b],dp[i-1][b][c]+(a==1));if(g==r&&s[i]=='B')dp[i][a][b]=max(dp[i][a][b],dp[i-1][b][c]+(a==1));}int res=-0x3f3f3f3f;for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)res=max(res,dp[n][i][j]);if(res<0)cout<<-1;elsecout<<res;return 0;
}

牛客寒假训练营1 K 冒险公社(线性dp)相关推荐

  1. 牛客寒假训练营4-爆炸的符卡洋洋洒洒 (dp变形)

    题意: 链接:登录-专业IT笔试面试备考平台_牛客网 来源:牛客网 小红正在研究如何把符卡组合出尽可能大威力的组合魔法. 小红共有 n 种符卡可以选择,每种符卡最多只能选择一次,每个符卡的魔力消耗为 ...

  2. 【牛客 - 696D】小K的雕塑(dp,鸽巢原理,01背包类问题)

    题干: 链接:https://ac.nowcoder.com/acm/contest/696/D 来源:牛客网 小K有n个雕塑,每个雕塑上有一个整数 若集合T中的每一个元素在n个雕塑上都能找得到,则称 ...

  3. 2021牛客寒假训练营5D石子游戏(差分)

    这个题无解的情况后台数据高达80%,一开始过了10%以为写假了 光巨昨晚讲的太好了,今天上线写一下 题目大意: 给你n堆石子和一个区间k,每次对一个长度一定为k的区间里的所有数字加一,问最少操作次数使 ...

  4. 牛客寒假训练营6 阿宁睡不醒

    题目: 题目链接:https://ac.nowcoder.com/acm/contest/46814/L 题意:输入n,m代表一个n*n的网格中有m个坏点,随后输入m行的x,y坐标,表示所有坏点的位置 ...

  5. 【牛客 - 315F】美丽的项链(线性dp,递推,我为人人)

    题干: 妞妞参加了Nowcoder Girl女生编程挑战赛, 但是很遗憾, 她没能得到她最喜欢的黑天鹅水晶项链. 于是妞妞决定自己来制作一条美丽的项链.一条美丽的项链需要满足以下条件: 1.需要使用n ...

  6. 2022牛客寒假算法基础集训营3 签到题7题(附基础集训营1-3签到题总结)

    1.A-智乃的Hello XXXX 签到 #include<bits/stdc++.h> using namespace std; int main(){cout<<" ...

  7. 2021牛客寒假算法基础集训营1 J 一群小青蛙呱蹦呱蹦呱

    今天的比赛没打( 睡午觉去了,今天太累了 晚上来看看题 2021牛客寒假算法基础集训营1 J 一群小青蛙呱蹦呱蹦呱 题目传送门 板子题( 我们知道由唯一分解定理得,若 n=p1α1×p2α2×p3α3 ...

  8. 2022牛客寒假算法基础集训营6 签到题5题(附基础集训营4-6签到题总结)

    1.I-A+B问题 模拟,类似于高精度,竖式运算 #include<bits/stdc++.h> using namespace std; typedef long long LL; in ...

  9. (构造+二进制)2020牛客寒假算法基础集训营3B.牛牛的DRB迷宫II

    2020牛客寒假算法基础集训营3B.牛牛的DRB迷宫II 思路: 一开始我是考虑全部都是B会怎么样,然后删改,结果到后面发现很难推到普遍规律(可能是因为我没看出来). 看了题解之后,觉得这题出的挺有意 ...

  10. 构造-牛客寒假集训营3-牛牛的DRB迷宫II

    构造-牛客寒假集训营3-牛牛的DRB迷宫II 题目: 题意: 输入一个数字,表示从起点(1,1)到终点(n,m)的方案数量,输出满足条件的迷宫.输入一个数字,表示从起点(1,1)到终点(n,m)的方案 ...

最新文章

  1. from __future__ import absolute_import, division, print_function
  2. pelco协议及其实现的简单认识
  3. hadoop交流群261039241
  4. 008/160 CrackMe Andrénalin #1
  5. Grand Canyon
  6. zookeeeper 启动失败 Unexpected exception, exiting abnormally java.io.eofexception
  7. git fsck --lost-found
  8. MacOS安装brew
  9. 游戏辅助制作核心----植物大战僵尸逆向之加速出僵尸(十)
  10. 看懂DNS到HttpDNS
  11. 计算机领域经典故事,[转载]计算机的工作原理(1):一个经典的故事
  12. 咦,为什么我的事务回滚不了?
  13. Elasticsearch+X-pack和Java Transport方式连接
  14. NSSCTF刷题wp——常用编码
  15. android开发和手游开发工具,developer盘点Android开发者必备十大开发工具
  16. 3d建模沟通能力,技术能力,更容易往主管,经理等管理方向发展
  17. 开发者模式的微信公众号菜单链接其他开发者的小程序
  18. 消除“你可能是盗版软件受害者”的提示(XP蓝星)
  19. 对于reflect: Elem of invalid type main.User类型的错误解释
  20. Mstar Amlogic智能电视芯片

热门文章

  1. ucml 连接虚字段
  2. 数字转成人民币汉字大写(李刚著《疯狂Python讲义》P87,解决小数部分及多个零的问题。学习笔记)
  3. python自动注册邮箱_Python自动登录126邮箱的方法
  4. 未来的计算机范文,未来的电脑作文(通用3篇)
  5. 分治策略-股票获取最大收益-最大子数组问题
  6. 准考证丢失后如何查询四六级成绩
  7. 龟兔赛跑Description乌龟与兔子在马路上赛跑,马路边可以随地进行休息。
  8. 2021最全HW蓝队指导手册
  9. 《数据库原理与应用》学习笔记(一):概论
  10. Drillbeach---第二章 Drillbench 5.1 Dynaflodrill 用户指南