前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【USACO1.1】Broken Necklace

【USACO1.1】Broken Necklace

作者头像
饶文津
发布2020-06-02 15:27:59
2910
发布2020-06-02 15:27:59
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏

题意

一个环形项链,有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("%d\n",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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-04-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题意
  • 分析
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档