【USACO1.1】Broken Necklace

2020-06-02 15:27:59 浏览数 (1)

题意

一个环形项链,有rbw三种珠子,r代表red,b代表blue,w代表white,从任意一个位置断开,两端分别取珠子,同一端取的珠子要相同颜色,w可以染成想要的颜色,即既可当作r也可以当作b,求最多取得的珠子个数。最多有350个珠子。

分析

可以枚举断开的位置,然后模拟取珠子。也可以枚举起点位置。还可以dp做。

代码

枚举断点

代码语言:javascript复制
#include<cstdio>
#include<algorithm>
#define N 355
using namespace std;

char a;
int b[N];
int n,ans;

int solve(int p,int dir) //p为起始点,dir为方向,求最多取几颗
{
    int len=0;//取了的珠子个数,最多取n颗珠子

    for(int j=p n; len<n; len  ,j =dir) //j为当前位置 n,当前位置为j%n
    {
        if(b[p] && b[j%n] && b[j%n]!=b[p])
            break;
        if(!b[p])//每次取珠子都要符合p位置的颜色,若p位置是w,就要更新p
            p=j%n;
    }
    return len;
}
int main()
{
    scanf("%d ",&n);
    for(int i=0; i<n; i  )
    {
        a=getchar();
        b[i]=a=='b'?1:a=='r'?2:0;// b--1 r--2 w--0
    }
    for(int i=0; i<n; i  )//枚举断点
        ans=max(ans,solve(i,-1) solve(i 1,1));
    ans=min(ans,n);//可能同一颗被两次计算过,但只出现在全都取的情况里
    printf("%dn",ans);
    return 0;
}

枚举起点

代码语言:javascript复制
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
int n,ans;
string s;
int main()
{
    cin>>n>>s;
    s =s;
    for(int i=0,j; i<n; i  ) //以i为第一段的起点,不是切开的位置
    {
        char now=s[i];
        int len=0;
        int times=now=='w'?3:2;//如果当前是白色,那么需要找三段相同颜色的否则找两段
        j=i;
        while(times--)
        {
            while(j<i n&&(s[j]==now||s[j]=='w'))
            {
                len  ;
                j  ;
            }
            now=s[j];
        }
        ans=max(ans,len);
    }
    cout<<ans<<endl;
    return 0;
}

DP

代码语言:javascript复制
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#define N 720
using namespace std;
int n,ans;
string s;
int l[N][2],r[N][2];
int main(){
    cin>>n>>s;
    s =s;
    for(int i=1;i<2*n;i  ){
        l[i][0]=l[i-1][0] 1;
        l[i][1]=l[i-1][1] 1;
        if(s[i-1]=='r')
            l[i][1]=0;
        else if(s[i-1]=='b')
            l[i][0]=0;
    }
    for(int i=2*n-1;i>=0;i--){
        r[i][0]=r[i 1][0] 1;
        r[i][1]=r[i 1][1] 1;
        if(s[i]=='r')
            r[i][1]=0;
        else if(s[i]=='b')
            r[i][0]=0;
    }
    for(int i=0;i<2*n;i  )
        ans=max(ans,max(l[i][0],l[i][1]) max(r[i][0],r[i][1]));
    ans=min(ans,n);
    cout<<ans<<endl;
    return 0;
}
dp

0 人点赞