算法连载6

来源:互联网 发布:视频直播间php源码 编辑:程序博客网 时间:2024/04/29 07:15

Problem Statement

 Little Fox Jiro has a rectangular board. On the board there is a row of N unit cells. The cells are numbered 0 through N-1 from the left to the right. Initially, the cells are not colored. Jiro must color each of the cells red, green, or blue.

You are given a string desiredColor with N characters. For each i, character i ofdesiredColor represents the color Jiro must use for cell i. If a character is one of 'R' (as red), 'G' (as green), and 'B' (as blue), it means that Jiro must use that particular color. If a character is '*', Jiro may use any of the three colors for the particular cell.

You are also given the ints stampCost and pushCost that describe the cost of the coloring process. The coloring process consists of two phases. In the first phase, Jiro must pick a single stamp he will then use to color all the cells. The length L of the stamp can be any integer between 1 and N, inclusive. A stamp of length L costs L*stampCost.

In the second phase, Jiro must repeatedly use the stamp to color the cells. Each use of the stamp works as follows:
  1. Jiro picks one of the three colors and pushes the stamp into ink of the chosen color C.
  2. Jiro picks a segment of L contiguous cells such that each of them is either uncolored or already has the color C. The segment must be completely inside the board. That is, the leftmost cell of the segment must be one of the cells 0 through N-L.
  3. Jiro pushes the stamp onto the chosen segment of cells. All the cells now have color C.
Each use of the stamp costs pushCost.

Return the smallest possible total cost of coloring all the cells using the above process.

Definition

 Class:StampMethod:getMinimumCostParameters:string, int, intReturns:intMethod signature:int getMinimumCost(string desiredColor, int stampCost, int pushCost)(be sure your method is public)  

Constraints

-desiredColor will contain between 1 and 50 characters, inclusive.-Each character of desiredColor will be either 'R' or 'G' or 'B' or '*'.-stampCost will be between 1 and 100,000, inclusive.-pushCost will be between 1 and 100,000, inclusive.

Examples

0)  
"RRGGBB"
1
1
Returns: 5
The optimal solution is to choose L=2 and then stamp three times: using red color for cells [0,1], green for [2,3], and blue for [4,5]. The stamp costs 2*1 = 2, each of the three uses costs 1, so the total costs is 2*1 + 3*1 = 5.1)  
"R**GB*"
1
1
Returns: 5
The optimal solution is the same as in the previous example. Note that you must color all the cells, so choosing L=1 and then using the stamp three times is not a valid solution.2)  
"BRRB"
2
7
Returns: 30
Also, note that once a cell is colored, you are not allowed to stamp over it using a different color. Therefore, you can only choose L=1 in this case.3)  
"R*RR*GG"
10
58
Returns: 204
It is allowed to stamp the same cell multiple times if all of those stamps use the same color.4)  
"*B**B**B*BB*G*BBB**B**B*"
5
2
Returns: 33
5)  
"*R*RG*G*GR*RGG*G*GGR***RR*GG"
7
1
Returns: 30

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.     


经过一个星期的努力总算完成了,好像太水了。但是我希望不只是做出来,而是更好,只有这样才会提高。有时简单的问题会被无限复杂化,所以要时刻头脑清醒。

我找不到题目在哪里了只好讲算法。

首先,我把数据处理成2个数列n,m 。n是连续的且有颜色,m是任意的。这样数据可以被处理成这样:

n1  n2   n3……    nx

m1     m2    m3 …… mx     m x+1

这样分完后,就是求最大的L。

mi里的数可以被分配到ni和ni-1 (当然不包括2端)。我们要坐的就是如何分配mi,使每个区域取到最大的L。

这个题目看上去好像没什么方法,遍历是可以的。在知道L为几时很容易验证。只要尽量先填满前面的。这个算法不确定性太大。


现在我介绍我x的算法。

当x=1是很明显L=n1+m1+m2。我的算法就是从这里开始。首先尽量填到mi+1,同时注意,如果L只能填到ni,那么久重新计数。

S=m1,t=0//(t为上次循环中余下的部分),S为有效的积累

L=n1+m1+m2

for(){

S=ni+(mi+1);

n++;

if( t+ni+m(i+1)>=L)

S+=L

else

{

S-mi-ni-m(i+1)<=(n-1) x<=S-m(i+1)-ni

这里的x 就是长度,x小于左边的范围说明对后面的无影响。那么S,n都应该重新设置。

右边的这个范围是不能大于的,不然就填出头了。

t=n*x-S;


}

}

写的好像有点乱,不知道看的懂不。

反正就是填区域,每一步i 尽量的填满mi+1这一格。不是每一步都刚刚好填满,所以要分各种情况,然后再总结下。


其实我没必要一次循环得出最大的L。比如别人的就简单多了。

#define MAX 100
int dp[MAX][5];
int len;
string str ;


int rec(int pos,int make_col)
{
if(pos>=SZ(str)) return -1;
int &ret=dp[pos][make_col];
if(ret!=-1) return ret;
ret=oo;

int must_col;
if(make_col==0) must_col='R';
if(make_col==1) must_col='G';
if(make_col==2) must_col='B';

for(int j=pos;j<pos+len;j++)
if(j>=SZ(str)) return oo;

for(int j=pos;j<pos+len;j++){
if(str[j]=='*') continue ;
if(str[j]!=must_col return oo;
}
for(int j=pos+1;j<pos+len;j++) ret=min(ret ,rec(j,make_col)+1);

for(int i=0;i<=2;i++)ret=min(ret,rec(pos+len,i)+1);

return ret;


}
class Stamp {
public:
int getMinimumCost(string desiredColor, int stampCost,int pusnCost)
{
ll best=oo;
str=desiredColor;
for(len=1;len<=SZ(str);len++)
{
mem(dp,-1);
int push_phase=oo;
for(int i=0;i<=2;i++)
push_phase=min (push_phase,rec(0,i)+1);

best=min(best,(ll)stampCost*(ll)len+(ll)push_phase*(ll)pushuCost;

}
return best; }

};