Broken Necklace
你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的。 这里是 n=29 的二个例子:
第一和第二个珠子在图片中已经被作记号。
图片 A 中的项链可以用下面的字符串表示:
brbrrrbbbrrrrrbrrbbrbbbbrrrrb .
假如你要在一些点打破项链,展开成一条直线,然后从一端开始收集同颜色的珠子直到你遇到一个不同的颜色珠子,在另一端做同样的事。(颜色可能与在这之前收集的不同) 确定应该在哪里打破项链来收集到最大多数的数目的子。 Example 举例来说,在图片 A 中的项链,可以收集到8个珠子,在珠子 9 和珠子 10 或珠子 24 和珠子 25 之间打断项链。 在一些项链中,包括白色的珠子如图片 B 所示。 当收集珠子的时候,一个被遇到的白色珠子可以被当做红色也可以被当做蓝色。 表现项链的字符串将会包括三符号 r , b 和 w 。 写一个程序来确定从一条被供应的项链最大可以被收集珠子数目。
SAMPLE INPUT
29
wwwbbrwrbrbrrbrbrwrwwrbwrwrrb
OUTPUT FORMAT
单独的一行包含从被供应的项链可以被收集的珠子数目的最大值。
SAMPLE OUTPUT
11
解题目分析如下:
如果采用反复搜索的算法也是可以,只是效率要低,使用动态规划记录已经计算过的值避免重复计算
以下标i分开将环形即展开为一条直线为
i-1...n...i
可以这样想,用red[i]和blue[i],对于第i个一珠子两种颜色的数目,从左至右进行收集,对于第i个珠子,如果我们知道从i=0开始到第i-1的珠子时能收集的相应颜色个数,那么对第个珠子来说就可能出现如下几种情况
1.如果i是红色,那么red[i] = red[i-1]+1,blue[i] = 0;
2.如果i是绿色,那么blue[i] = blue[i]+1,red[i] = 0;
3.如果i是白色,那么red[i] = rad[i-1]+1 并且 blue[i] = blue[i-1]+1;
类似从右至左也是一样,即[i] 与 [i+1]之间的关系
举一个简单的例子:123456将其从任意点断开的形式有,用i表示下标从0..n-1
123456 从0处断开,这时应该扫描两端从左至右和从右至左收集满足条件的
234561 从1处断开
345612 ...2..
456123 ...3..
561234 ....4...
612345 ....5...
从上面可以看出对n个元素的项链有n种不同的分折法
对于从左至右时可以将原数组修改为123456123456
通过上述分析则得出对于任意分折点i,有left[i],right[i]的珠子个数,这样求最大的和 max(toLeft[i]+toRight[i]) 即为要求的解
因为有红和绿之分,分别求出toLeft[i]中红与绿的最大值max(toLeft[i][0],toLeft[i][1]),toLeft[i][0]表示绿,toLeft[i][1]表示红...
toRight类似
#include < string .h >
int getMax( int a, int b)
{
return a