[LuoguP1203][USACO1.1]P1203 Broken Necklace
Solution
这道题数据规模奇小,因此大部分人都使用了暴力搜索的方法,这也是我一开始的想法。
对于 100100%100 的数据,3≤n≤3503≤n≤3503≤n≤350
的确可以如此,但暴力搜索的方法也需要进行一些奇怪的判断,因此我又决定直接打dp的解法,其实dp也是很自然的一种想法……
Dynamic Programming
我们可以发现,每个点向左向右,取蓝色取红色能连续取的个数一定是确定的。
于是我们定义dp数组:
int lr[maxn];
//lr[i]代表从i点向左不取i点
//即在 [1,i-1] 范围内从i-1开始能连续取多少个红色珠子
int lb[maxn];
//lb[i]代表从i点向左不取i点
//即在 [1,i-1] 范围内从i-1开始能连续取多少个蓝色珠子
int rr[maxn];
//rr[i]代表从i点向右取i点
//即在[i,n] 范围内从i开始能连续取多少个红色珠子
int rb[maxn];
//rb[i]代表从i点向右取i点
//即在[i,n] 范围内从i开始能连续取多少个蓝色珠子
那么在一个点断开,能取得的珠子个数就是:
ans[i]=max(lr[i],lb[i])+max(rr[i],rb[i])ans[i] = max(lr[i],lb[i]) + max(rr[i],rb[i])ans[i]=max(lr[i],lb[i])+max(rr[i],rb[i])
相信转移方程非常自然吧,我们先考虑向左取的情况:
- 前一个点为白色,那么有:
lr[i]=lr[i−1]+1lr[i] = lr[i-1] + 1lr[i]=lr[i−1]+1
lb[i]=lb[i−1]+1lb[i] = lb[i-1] + 1lb[i]=lb[i−1]+1 - 前一个点为红色,那么有:
lr[i]=lr[i−1]+1lr[i] = lr[i-1] + 1lr[i]=lr[i−1]+1
lb[i]=0lb[i] = 0lb[i]=0 - 前一个点为蓝色,那么有:
lr[i]=0lr[i] = 0lr[i]=0
lb[i]=lb[i−1]+1lb[i] = lb[i-1] + 1lb[i]=lb[i−1]+1
为什么考虑前一个点呢?
因为lr[i]lr[i]lr[i]和lb[i]lb[i]lb[i]代表的是区间[1,i−1][1,i-1][1,i−1]内从点i−1i-1i−1开始取能连续取多少,因此实际考虑的是点i−1i-1i−1的颜色。
向右的情况也是同理,有:
- 当前点为白色,那么有:
rr[i]=rr[i+1]+1rr[i] = rr[i+1] + 1rr[i]=rr[i+1]+1
rb[i]=rb[i+1]+1rb[i] = rb[i+1] + 1rb[i]=rb[i+1]+1 - 当前点为红色,那么有:
rr[i]=rr[i+1]+1rr[i] = rr[i+1] + 1rr[i]=rr[i+1]+1
rb[i]=0rb[i] = 0rb[i]=0 - 当前点为蓝色,那么有:
rr[i]=0rr[i] = 0rr[i]=0
rb[i]=rb[i+1]+1rb[i] = rb[i+1] + 1rb[i]=rb[i+1]+1
实现也很简单:
for (int i = 2; i <= n; ++i)
{
if (s[i - 1] == 'w')
lb[i] = lb[i - 1] + 1, lr[i] = lr[i - 1] + 1;
else if (s[i - 1] == 'b')
lb[i] = lb[i - 1] + 1, lr[i] = 0;
else
lb[i] = 0, lr[i] = lr[i - 1] + 1;
}
for (int i = n - 1; i; --i)
{
if (s[i] == 'w')
rb[i] = rb[i + 1] + 1, rr[i] = rr[i + 1] + 1;
else if (s[i] == 'b')
rb[i] = rb[i + 1] + 1, rr[i] = 0;
else
rb[i] = 0, rr[i] = rr[i + 1] + 1;
}
Finally
于是我们处理出了每个点向左向右取红取蓝最多能连续取多少个珠子。
那么从i−1i-1i−1点,向左最多能取多少呢?
left[i−1]=max(lr[i],lb[i])left[i-1] = max(lr[i],lb[i])left[i−1]=max(lr[i],lb[i])
从iii点,向右最多能取
right[i]=max(rr[i],rb[i])right[i] = max(rr[i],rb[i])right[i]=max(rr[i],rb[i])
假定我们断开i−1i-1i−1和iii,那么答案就是:
ans=left[i−1]+right[i]ans = left[i-1] + right[i]ans=left[i−1]+right[i]
即
ans=max(lr[i],lb[i])+max(rr[i],rb[i])ans = max(lr[i],lb[i]) + max(rr[i],rb[i])ans=max(lr[i],lb[i])+max(rr[i],rb[i])
最后扫一遍统计答案即可。
int ans = 0;
for (int i = 1; i <= n; ++i)
ans = max(ans, max(lb[i], lr[i]) + max(rb[i], rr[i]));
当然,还要注意答案不能超过原始的长度。
Code
拆环为链等细节就不赘述了。
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 710;
char s[maxn];
int n,lb[maxn], lr[maxn], rb[maxn], rr[maxn];
inline int max(const int &a, const int &b) { return a > b ? a : b; }
int main()
{
scanf("%d%s", &n, s + 1);
memcpy(s + n + 1, s + 1, n);
n <<= 1;
for (int i = 2; i <= n; ++i)
{
if (s[i - 1] == 'w')
lb[i] = lb[i - 1] + 1, lr[i] = lr[i - 1] + 1;
else if (s[i - 1] == 'b')
lb[i] = lb[i - 1] + 1, lr[i] = 0;
else
lb[i] = 0, lr[i] = lr[i - 1] + 1;
}
for (int i = n - 1; i; --i)
{
if (s[i] == 'w')
rb[i] = rb[i + 1] + 1, rr[i] = rr[i + 1] + 1;
else if (s[i] == 'b')
rb[i] = rb[i + 1] + 1, rr[i] = 0;
else
rb[i] = 0, rr[i] = rr[i + 1] + 1;
}
int ans = 0;
for (int i = 1; i <= n; ++i)
ans = max(ans, max(lb[i], lr[i]) + max(rb[i], rr[i]));
if (ans > n >> 1)
ans = n >> 1;
printf("%d\n", ans);
return 0;
}
[LuoguP1203][USACO1.1]P1203 Broken Necklace的更多相关文章
- 【USACO1.1】Broken Necklace
题意 一个环形项链,有rbw三种珠子,r代表red,b代表blue,w代表white,从任意一个位置断开,两端分别取珠子,同一端取的珠子要相同颜色,w可以染成想要的颜色,即既可当作r也可以当作b,求最 ...
- P1203 [USACO1.1]坏掉的项链Broken Necklace
P1203 [USACO1.1]坏掉的项链Broken Necklace不错的断环为链的模拟题,开成三倍,有很多细节要考虑,比如总长度要<=n,开头第一个是w等等. #include<bi ...
- 【P1203】 【USACO1.1】坏掉的项链Broken Necklace
P1203 [USACO1.1]坏掉的项链Broken Necklace 题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 ...
- P1203 [USACO1.1]Broken Necklace(模拟-枚举)
P1203 [USACO1.1]坏掉的项链Broken Necklace 题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 ...
- 题解 P1203 【[USACO1.1]坏掉的项链Broken Necklace】
[USACO1.1]坏掉的项链Broken Necklace 22892 破碎的项链 方法一:很容易想到枚举断点,再分别两头找,但是要注意很多细节 #include<iostream> # ...
- 洛谷 P1203 [USACO1.1]坏掉的项链Broken Necklace
坏掉的项链Broken Necklace 难度:★ Code: #include <iostream> #include <cstdio> #include <cstri ...
- [USACO1.1.4]坏掉的项链Broken Necklace
P1203 [USACO1.1]坏掉的项链Broken Necklace 标签 搜索/枚举 USACO 难度 普及- 题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N&l ...
- 洛谷P1203 [USACO1.1]坏掉的项链Broken Necklace
题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 n=29 的二个例子: 第一和第二个珠子在图片中已经被作记号. 图片 A ...
- AC日记——[USACO1.1]坏掉的项链Broken Necklace 洛谷 P1203
题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 n=29 的二个例子: 第一和第二个珠子在图片中已经被作记号. 图片 A ...
随机推荐
- php之新的开始---php的相关及其环境搭建
写在前面:首先,感谢“奇矩”给的这次机会,不论结果如何,我都会尽我最大的努力! 在今晚之前,如果说,我与php的接触是停留在知道的阶段,那今晚过后,我想我算是认识了php.php作为一门编程语言,已经 ...
- Shell编程WEB界面展示实践
操作系统:win7 虚拟机:Virtual box with Ubuntu13.10 WEB服务器: Nginx WEB服务器发布目录:/usr/local/nginx/html/c 测试文件:lis ...
- xml 写sql语句文件头
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-/ ...
- python2.7升级到python3后,用pip进行安装时报Fatal error in launcher:Unbale to create process using`""
解决:python2.7升级到python3后,用pip进行安装时报Fatal error in launcher:Unbale to create process using`"" ...
- 第二十九节: Asp.Net Core零散获取总结(不断补充)
1. IWebHostEnvironment获取常用属性 (1).获取项目的根目录 _env.ContentRootPath 等价于 Directory.GetCurrentDirectory() ( ...
- 2.ORM框架添加,修改,删除操作
创建了表对象,代码如下: from flask import Flask from flask_sqlalchemy import SQLAlchemy app=Flask(__name__) # 配 ...
- Mysql 分组查询出现'this is incompatible with sql_mode=only_full_group_by'的解决办法
由于Mysql自动开启了 only_full_group_by,所以若查询的字段不在group by里面,则分组报错. 解决办法其一:mysql配置,关闭only_full_group_by,这种办法 ...
- 使用KVC键值编码
掌握KVC从不使用setter.getter.点语法开始. ----- 前言 对象的内部状态是由属性进行封装的.访问对象属性的方式平时在开发过程中用得最多的是getter方法和点语法.键值编程KVC也 ...
- Preparing for the interview of FLAG and USDA
7,Dynamic Programming 1,Unique Paths A robot is located at the top-left corner of a m x n grid (mark ...
- pymongo 用户密码连接
# db mongodbdb_mongo_attr = { 'host': '*', 'port': 27, 'database':'tease', 'username':'*v', 'passwor ...