beads解题报告 —— icedream61 博客园(转载请注明出处)
------------------------------------------------------------------------------------------------------------------------------------------------
【题目】
  输入文件:第一行N;第二行一个字符串A,长度为N。字符串中,仅有r、w、b三种字符,分别代表红、白、蓝。
  A代表一串项链,有三种颜色的珠子。将A首位相接,而后从一个地方断开,形成新的串B。从B首尾分别开始向中间按以下规则取珠子,求最多得到多少颗。
  规则:每边都连续取,不能跳;只能取一种颜色的珠子,w可以视为任何颜色。例如rwwrrwbwr,左边能取6个,w视为r;右边只能取2个,因为有r且不能跳过b。
【数据范围】
  3<=N<=500
【输入文件】
  77
  rwrwrwrwrwrwrwrwrwrwrwrwbwrwbwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwr
【输出文件】
  74
------------------------------------------------------------------------------------------------------------------------------------------------
【分析1——暴力】
  本题数据很小,枚举法即可。N个分割位置,每个位置最多数2N个珠子,时间复杂度是O(N²)。
  本题难点在于,数珠子要求一定的编程严谨性。
【分析2——NEW】
  本题基本思路,枚举N个位置,N个分割结果中取最大值即为答案。
  从每个位置往两侧数,加起来再去重(所有珠子都可以取的时候会产生重复)就是从这里分割的结果了。
  那么,我们可以考虑降低从某个位置往两侧数的时间。假设当前处于位置i,珠子颜色是r,正在向右数。显然应当数到第一个b为止。而这条路径上的所有r,都应数到同一个b为止;所有w,则除了紧贴着b的几个w外,都应数到b为止。那么,我们便可以考虑,把这些点数一次就统统解决,减少重复的时间。
  为了达到上述效果,我们反过来考虑:如果我站在某个b的位置上(这个位置记为k),往左看,则可以看到很多w和b,再继续则会看到很多r和w。那么,我从这个b往左一直走,走到的第一个r位置记为j,从j再继续走看到的第一个b位置记为i。显然,i+1到j的所有珠子向右数的结果我就都能确定下来了,就是数到k-1为止;同时,j+1到k的所有珠子向左数的结果我也都能确定下来了,就是数到j+1为止。(看到这里,脑子乱的同学一定要画个图来看看!)
  我们仔细看看上面的过程,到底是什么地方让我们一下子就确定下来这么多点的呢?没错!就是相邻的r和b~(当然,中间的w不影响“相邻”这个说法。)因此,我们可以考虑实际操作的时候从这里入手:先从随便一个地方开始扫,扫到第一个非w的地方记为x,不妨设这里是r;而后,再继续扫,找到第一个b位置记为z。(如果扫完一圈都找不到b,那么本题答案是N。)那么此时,我们记z左边的第一个r位置是y,这在从x扫到z的过程中很容易顺带求出来。如此一来,我们就得到了相邻的两个珠子,左边的y是r,右边的z是b。此时,从z开始继续向右扫,直到第一个r为止,此处记为x(之前的x没用了,扔掉)。这个过程中,z到x-1的所有珠子向左都是数到y+1为止。而此时,我们又得到了第二组相邻的珠子,右边的x是r,而左边的则是刚才过程中记下来的x左边第一个b,于是,重复上述过程即可……直至找到所有珠子向左数的结果。
  这样做有些乱,建议大家一定要画个图理清思路,否则一定是编不对的……不过别沮丧,我们可是硬生生地把复杂度从O(N²)降到了O(N)啊!作为小作者的我,还是非常有成就感的^.^
【分析3——DP】
  本题考虑使用DP,仍是去降低数数的时间。
  定义:对于位置i的珠子,向左数结果为L[i],向右数结果为R[i]。
  定义:对于位置i的w珠子,向左数的过程中此点被视为的颜色为Lc[i],左边连续的w个数(包括自己)为Ln[i];右侧对应记为Rc[i]与Rn[i]。
  状态转移方程:
    对于位置i颜色r的珠子,
      1.如果i-1是r,那么L[i]=L[i-1]+1;
      2.如果i-1是b,那么L[i]=1;
      3.如果i-1式w,那么L[i]=(Lc[i-1]=='r')?(L[i-1]+1):(Ln[i]+1);
    对于位置i颜色w的珠子,那么L[i]=L[i-1]+1;
      1.如果i-1有颜色,那么Lc[i]为i-1的颜色,Ln[i]=1;
      2.如果i-1无颜色,那么Lc[i]=Lc[i-1],Ln[i]=Ln[i-1]+1;
    右侧则对称定义即可。
  边界条件:开始随便找一个点,位置记为i。从i向两侧数出i点所有信息即可。
  DP过程:从i点向右DP直至绕一圈到i-1,再同样从i点向左DP到i+1。
  至此,每个点向左向右数的结果都已知晓,直接枚举所有位置求出答案即可,时间复杂度O(N)。
------------------------------------------------------------------------------------------------------------------------------------------------
【总结】
  这道题我犯了几个细节错误,充分说明了我现在手生。
  犯的错误有
    1.忘了答案超过N时去重
    2.在C/C++中,当i<0,N>0时,i%N结果为i,而不是i+N。因此,当往左数的时候,要将i=(i-1)%N写成i=(i-1+N)%N。
  注:我写的是方法1。

------------------------------------------------------------------------------------------------------------------------------------------------

【代码】

 /*
ID: icedrea1
PROG: beads
LANG: C++
*/ #include <iostream>
#include <fstream>
using namespace std; int N;
string B; char now(char x,char y)
{
return x=='w'?y:x;
}
bool good(char x,char y)
{
return x==y || x=='w' || y=='w';
}
int go(int i,int add)
{
bool p=false;
if(i> && i<) p=true;
if(p) cout<<"i="<<i<<"\tadd="<<add<<"\t"<<B[i];
int s=;
char x=B[i];
for(i=(i+add+N)%N;
good(x,B[i]) && s<N;
i=(i+add+N)%N)
{
++s;
x=now(x,B[i]);
}
if(p) cout<<"\ts="<<s<<"\ti="<<i<<endl;
return s;
}
void change(int &r,int x)
{
static int time = ;
if(x>r) r=x;
//if(--time>0 && time<34) cout<<"\tx="<<x<<"\n"<<endl;
}
int main()
{
ifstream in("beads.in");
ofstream out("beads.out"); int r=;
in>>N>>B;
cout<<"B[0]="<<B[]<<endl;
cout<<"B[N-1]="<<B[N-]<<endl;
for(int i=;i!=N;++i)
{
// selebrate i and i+1
change(r,go(i,-)+go((i+)%N,));
}
out<<(r<N?r:N)<<endl; in.close();
out.close();
return ;
}

USACO Section1.1 Broken Necklace 解题报告的更多相关文章

  1. USACO Section1.5 Prime Palindromes 解题报告

    pprime解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...

  2. USACO Section1.5 Superprime Rib 解题报告

    sprime解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...

  3. USACO Section1.5 Number Triangles 解题报告

    numtri解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...

  4. USACO Section1.4 Arithmetic Progressions 解题报告

    ariprog解题报告 —— icedream61 博客园(转载请注明出处)-------------------------------------------------------------- ...

  5. USACO Section1.3 Combination Lock 解题报告

    combo解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...

  6. USACO Section1.3 Prime Cryptarithm 解题报告

    crypt1解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...

  7. USACO Section1.3 Barn Repair 解题报告

    barn1解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...

  8. USACO Section1.3 Mixing Milk 解题报告

    milk解题报告 —— icedream61 博客园(转载请注明出处)----------------------------------------------------------------- ...

  9. USACO Section1.2 Palindromic Squares 解题报告

    palsquare解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------ ...

随机推荐

  1. API:相关词语笔记

    1.SDK 软件开发套件,接口服务器把接口开发之后,把怎么使用的示范代码弄出来给API客户端的开发者参考. 2.头部信息 对头部信息的特殊符号有要求,例如: 持续更新中....

  2. Sliding Window - The Smallest Window II(AIZU) && Leetcode 76

    http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_3_B For a given array a1,a2,a3,...,aNa1 ...

  3. 将TIMESTAMP类型的差值转化为秒的方法

    两个TIMESTAMP之差得到的是INTERVAL类型,而有时我们只需要得到两个时间相差的秒数,如果变成INTERVAL之后,想要获取这个值会非常麻烦. 比较常见的方法是使用EXTRACT来抽取获得的 ...

  4. 了解iOS上的可执行文件和Mach-O格式

    http://www.cocoachina.com/mac/20150122/10988.html http://www.reinterpretcast.com/hello-world-mach-o ...

  5. create-react-app项目使用假数据

    做新项目的时候,前端每次要等后端接口准备好再开始,就会延期,等后端接口准备好了,前端这边的项目又会相互紧张,如果前端跟后端同时进行,前期将框架,基础做好,定好接口文档,前端在后端没准备好接口的时候使用 ...

  6. spring boot学习1

    转:https://blog.csdn.net/jsyxcjw/article/details/46763639 1 开始 1.1 spring介绍 Spring Boot使开发独立的,产品级别的基于 ...

  7. 矩阵——特征向量(Eigenvector)

    原文链接 矩阵的基础内容以前已经提到,今天我们来看看矩阵的重要特性——特征向量. 矩阵是个非常抽象的数学概念,很多人到了这里往往望而生畏.比如矩阵的乘法为什么有这样奇怪的定义?实际上是由工程实际需要定 ...

  8. 微信端H5页面问题总结

    1.div元素不确定高度的情况下背景图片显示问题,解决后可以自适应不同分辨率的屏幕大小,div元素的background-size设置100%后,其自身的高度和宽度不能再设置. .register-t ...

  9. 3.Netty的粘包、拆包(二)

    Netty提供的TCP数据拆包.粘包解决方案 1.前言 关于TCP的数据拆包.粘包的介绍,我在上一篇文章里面已经有过介绍. 想要了解一下的,请点击这里 Chick Here! 今天我们要讲解的是Net ...

  10. node-inspector调试工具使用方法

    开发node.js程序使用的是javascript语言,其中最麻烦的还是调试,这里介绍一下node-inspector使用方法.具体资料可以看参考资料中的GITHUB文档. 工具/原料   node. ...