USACO 1.1 Broken Necklace(USACO官方)

本题我不会写,囧,看了官方的代码,算法复杂度为O(n^2),学习下:

/*
  ID:twd30651
  PROG:beads
  LANG:C++
*/
#include<iostream>
#include<fstream>
#include<string.h>
using namespace std;
int N;
char s[400];
int len;
int mod(int n,int m)
{
    while(n<0)n+=m;
    return n%m;//值得学习,跑一圈又回来
}
int nbreak(int p,int dir)
{
    int i;
    int n;
    if(dir>0)
        i=p;
    else
        i=mod(p-1,len);
    char color='w';//用color来保存颜色
    for(n=0;n<len;i=mod(i+dir,len))
    {
        if(color=='w'&&s[i]!='w')
            color=s[i];//处理收集珠子时颜色的变换
        else if(color!=s[i]&&s[i]!='w')
            break;
        n++;
    }
    return n;
}
int main(int argc,char *argv[])
{
    freopen("beads.in","r",stdin);
    freopen("beads.out","w",stdout);
    int i=0;
    scanf("%d",&N);
    scanf("%s",s);
    len=strlen(s);
    int n;
    int m=0;
    for(i=0;i<len;++i)
    {
        n=nbreak(i , 1)+nbreak(i,-1);//兵分两路
        if(n>m)
            m=n;
    }
    if(m>len)//考虑转了一圈,又回来了,类似于"rrrrrr"这样的字符串
        m=len;
    printf("%d\n",m);
    return 0;
}

下面一种方法是dp,时间复杂度为O(n)

/*
  ID:twd30651
  PROG:beads
  LANG:C++
*/
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<string.h>
using namespace std;
/*
  copy:
  用数组bl,br,rl,rr分别记录在项链i处向左向右收集的蓝色红色珠子数。
  项链是环形的,但我们只要把两个同样的项链放在一块,就把它转换成线性的了。
  我们只要求出bl,br,rl,rr,那么结果就是max(max(bl[i],rl[i])+max(br[i+1],rr[i+1])) (0<=i<=2*n-1)。
  我们以求bl,rl为例:
  初始时bl[0]=rl[0]=0
  我们从左往右计算
  如果necklace[i]='r',rl[i]=rl[i-1]+1,bl[i]=0;
  如果necklace[i]='b', bl[i]=bl[i-1]+1,rl[i]=0;
  如果necklace[i]='w',bl[i]=bl[i-1]+1,rl[i]=rl[i-1]+1。
  同理可以求出br,rr。
*/
typedef struct node
{
    int lr;//向左最多红色珠子
    int lb;//向左最多蓝色珠子
    int rr;//向右最多红色珠子
    int rb;//向右最多蓝色珠子
}node;
node necklace[800];
char s[800];
char tmp[400];
int N;
int main(int argc,char *argv[])
{
    freopen("beads.in","r",stdin);
    freopen("beads.out","w",stdout);
    int i=0;
    scanf("%d",&N);
    scanf("%s",s);
    strcpy(tmp, s);
    //也是珠子加上它自己的一个副本
    strcat(s, tmp);
    necklace[0].lr=0;
    necklace[0].lb=0;
    for(int i=1;i<=2*N;++i)
    {
        if(s[i-1]=='r')
            necklace[i].lr=necklace[i-1].lr+1,necklace[i].lb=0;
        else if(s[i-1]=='b')
            necklace[i].lb=necklace[i-1].lb+1,necklace[i].lr=0;
        else
            necklace[i].lb=necklace[i-1].lb+1,
                necklace[i].lr=necklace[i-1].lr+1;
    }
    necklace[2*N].rr=0;
    necklace[2*N].rb=0;
    for(int i=2*N-1;i>=0;--i)
    {
        if(s[i]=='r')
            necklace[i].rr=necklace[i+1].rr+1,necklace[i].rb=0;
        else if(s[i]=='b')
            necklace[i].rb=necklace[i+1].rb+1,necklace[i].rr=0;
        else
            necklace[i].rb=necklace[i+1].rb+1,
                necklace[i].rr=necklace[i+1].rr+1;
    }
    int m=0;
    for(int i=0;i<2*N;++i)
        m=max(m,max(necklace[i].lr,necklace[i].lb)
              +
              max(necklace[i].rr, necklace[i].rb));
    if(m>N)
        m=N;
    printf("%d\n",m);
    return 0;
}


你可能感兴趣的:(USACO,Broken,Necklace,beads)