Broken Necklace
You have a necklace of N red, white, or blue beads (3<=N<=350) some of which are red, others blue, and others white, arranged at random. Here are two examples for n=29:
1 2 1 2 r b b r b r r b r b b b r r b r r r w r b r w w b b r r b b b b b b r b r r b r b r r r b r r r r r r b r b r r r w Figure A Figure B r red bead b blue bead w white bead
The beads considered first and second in the text that follows have been marked in the picture.
The configuration in Figure A may be represented as a string of b's and r's, where b represents a blue bead and r represents a red one, as follows: brbrrrbbbrrrrrbrrbbrbbbbrrrrb .
Suppose you are to break the necklace at some point, lay it out straight, and then collect beads of the same color from one end until you reach a bead of a different color, and do the same for the other end (which might not be of the same color as the beads collected before this).
Determine the point where the necklace should be broken so that the most number of beads can be collected.
Example
For example, for the necklace in Figure A, 8 beads can be collected, with the breaking point either between bead 9 and bead 10 or else between bead 24 and bead 25.
In some necklaces, white beads had been included as shown in Figure B above. When collecting beads, a white bead that is encountered may be treated as either red or blue and then painted with the desired color. The string that represents this configuration can include any of the three symbols r, b and w.
Write a program to determine the largest number of beads that can be collected from a supplied necklace.
PROGRAM NAME: beads
INPUT FORMAT
Line 1: | N, the number of beads |
Line 2: | a string of N characters, each of which is r, b, or w |
SAMPLE INPUT (file beads.in)
29 wwwbbrwrbrbrrbrbrwrwwrbwrwrrb
OUTPUT FORMAT
A single line containing the maximum of number of beads that can be collected from the supplied necklace.
SAMPLE OUTPUT (file beads.out)
11
OUTPUT EXPLANATION
Consider two copies of the beads (kind of like being able to runaround the ends). The string of 11 is marked.
Two necklace copies joined here v wwwbbrwrbrbrrbrbrwrwwrbwrwrrb|wwwbbrwrbrbrrbrbrwrwwrbwrwrrb ******|***** rrrrrb|bbbbb <-- assignments 5xr .....#|##### 6xb 5+6 = 11 total
题意:将项链从i点分开,形成以i为右端点最长颜色相同的珠宝串,和以i-1为左端点最长颜色相同的珠宝串。求形成的两个珠宝串的最大和
题解:简单的dp,但情况种类较多 注意分析
dp1[i]是以i为右端点最长颜色相同珠宝个数,
dp1[i]=dp[i-1]+1 或dp1[i]=1+sumw1;
dp2[i]是以i为左端点最长颜色相同珠宝个数
dp2[i]=dp2[i+1]+1 或 dp2[i]=1+sumw2;
ps:本人大三狗一枚,正在持续更新博客,文章里有任何问题,希望各位网友可以指出。若有疑问也可在评论区留言,我会尽快回复。希望能与各位网友互相学习,谢谢!
/*
ID: cxq_xia1
PROG: beads
LANG: C++
*/
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=355;
int N;
char beads[maxn];
int calculate()
{
int dp1[maxn],dp2[maxn]; //dp1[i]是以i为右端点最长颜色相同珠宝个数,dp2[i]是以i为左端点最长颜色相同珠宝个数
int sumw1=0,sumw2=0; //sumw1记忆连着beads[i]左端连续白色珠宝的个数,sumw2记忆连着beads[i]右端连续白色珠宝的个数
int N1=2*N-1; //项链上珠宝个数的2倍 数组从0开始
char memory1='w',memory2='w'; //memory1记录i左端连续珠宝串的颜色,memory2记录i右端连续珠宝串的颜色
int ans=0;
for(int i=0;i<=N1;i++)
{
if(i==0)
{
if(beads[i]=='w')
sumw1=1;
else
memory1=beads[i];
dp1[i]=1;
if(beads[(N1-i)%N]=='w')
sumw2=1;
else
memory2=beads[(N1-i)%N];
dp2[(N1-i)%N]=1;
continue;
}
//推算dp1[i]
if(beads[i%N]=='w')
{
dp1[i%N]=dp1[(i-1)%N]+1;
sumw1++;
}
else if(beads[i%N]==beads[(i-1)%N])
{
dp1[i%N]=dp1[(i-1)%N]+1;
sumw1=0;
}
else if(beads[(i-1)%N]=='w')
{
if(memory1==beads[i%N])
dp1[i%N]=dp1[(i-1)%N]+1;
else
{
dp1[i%N]=1+sumw1;
memory1=beads[i%N];
}
sumw1=0;
}
else
{
dp1[i%N]=1+sumw1;
memory1=beads[i%N];
sumw1=0;
}
//推算dp2[N1-i]
if(beads[(N1-i)%N]=='w')
{
dp2[(N1-i)%N]=dp2[(N1-i+1)%N]+1;
sumw2++;
}
else if(beads[(N1-i)%N]==beads[(N1-i+1)%N])
{
dp2[(N1-i)%N]=dp2[(N1-i+1)%N]+1;
sumw2=0;
}
else if(beads[(N1-i+1)%N]=='w')
{
if(memory2==beads[(N1-i)%N])
dp2[(N1-i)%N]=dp2[(N1-i+1)%N]+1;
else
{
dp2[(N1-i)%N]=1+sumw2;
memory2=beads[(N1-i)%N];
}
sumw2=0;
}
else
{
dp2[(N1-i)%N]=1+sumw2;
memory2=beads[(N1-i)%N];
sumw2=0;
}
if(dp1[i%N]>=N) //整串项链都是同色
return N;
}
for(int i=0;i<N;i++)
{
if(i==N-1)
{
if(dp1[i]+dp2[0]>ans)
{
ans=dp1[i]+dp2[0];
}
continue;
}
if(dp1[i]+dp2[i+1]>ans)
{
ans=dp1[i]+dp2[i+1];
}
}
if(ans>=N) // rrwwwwbb 不加过不了
ans=N;
return ans;
}
int main()
{
freopen("beads.in","r",stdin);
freopen("beads.out","w",stdout);
while(cin >> N)
{
int ans;
for(int i=0;i<N;i++)
{
cin >> beads[i];
}
ans=calculate();
cout <<ans <<endl;
}
return 0;
}