Showing posts with label SRM. Show all posts
Showing posts with label SRM. Show all posts

Sunday, August 4, 2013

[TopCoder] SRM 586 DIV 2, 500p, 1000p, Solution

Problem Statement
    
F is a function that is defined on all real numbers from the closed interval [1,N]. You are given a vector <int> Y with N elements. For each i (1 <= i <= N) we have F(i) = Y[i-1]. Additionally, you know that F is piecewise linear: for each i, on the interval [i,i+1] F is a linear function. The function F is uniquely determined by this information. For example, if F(4)=1 and F(5)=6 then we must have F(4.7)=4.5.

As another example, this is the plot of the function F for Y = {1, 4, -1, 2}.



You are also given a vector <int> query. For each i, compute the number of solutions to the equation F(x) = query[i]. Note that sometimes this number of solutions can be infinite.

Return a vector <int> of the same length as query. For each i, element i of the return value should be -1 if the equation F(x) = query[i] has an infinite number of solutions. Otherwise, element i of the return value should be the actual number of solutions this equation has.
Definition
    
Class:
PiecewiseLinearFunctionDiv2
Method:
countSolutions
Parameters:
vector <int>, vector <int>
Returns:
vector <int>
Method signature:
vector <int> countSolutions(vector <int> Y, vector <int> query)
(be sure your method is public)
    
Constraints
-
Y will contain between 2 and 50 elements, inclusive.
-
Each element of Y will be between -1,000,000,000 and 1,000,000,000, inclusive.
-
query will contain between 1 and 50 elements, inclusive.
-
Each element of query will be between -1,000,000,000 and 1,000,000,000, inclusive.
Examples
0)
    
{1, 4, -1, 2}
{-2, -1, 0, 1}
Returns: {0, 1, 2, 3 }
This is the example from the problem statement. The detailed information about the queries is:
  • There is no such x that F(x) = -2 is satisfied.
  • F(x) = -1 is only true for x = 3.
  • F(x) = 0 has two roots: 2.8 and 10/3.
  • F(x) = 1 has three roots: 1, 2.6 and 11/3.
1)
    
{0, 0}
{-1, 0, 1}
Returns: {0, -1, 0 }
This function's plot is a horizontal segment between points (1, 0) and (2, 0). F(x) = 0 is satisfied for any x between 1 and 2 and thus the number of solutions is infinite. For any other value on the right-hand side, it has no solutions.
2)
    
{2, 4, 8, 0, 3, -6, 10}
{0, 1, 2, 3, 4, 0, 65536}
Returns: {3, 4, 5, 4, 3, 3, 0 }
3)
    
{-178080289, -771314989, -237251715, -949949900, -437883156, -835236871, -316363230, -929746634, -671700962}
{-673197622, -437883156, -251072978, 221380900, -771314989, -949949900, -910604034, -671700962, -929746634, -316363230}
Returns: {8, 6, 3, 0, 7, 1, 4, 8, 3, 4 }
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.
 

[Thoughts]  
把Y中连续的两个数字作为一个区间,然后对于每一个Q[i],遍历所有Y区间,统计覆盖次数即可。

[Code]  
1:  #include<vector>  
2:  using namespace std;  
3:  class PiecewiseLinearFunctionDiv2  
4:  {  
5:  public:  
6:       vector <int> countSolutions(vector <int> Y, vector <int> query)  
7:       {  
8:            vector<int> result;  
9:            for(int i =0; i< query.size(); i++)  
10:            {  
11:                 int searchNum = query[i];  
12:                 int start = 0;  
13:                 int solution=0;  
14:                 if(searchNum == Y[start]) solution++;  
15:                 for(int j =1; j< Y.size(); j++)  
16:                 {  
17:                      if(max(Y[start], Y[j]) > searchNum && min( Y[start], Y[j]) < searchNum)  
18:                      {  
19:                           solution++;                           
20:                      }  
21:                      if(searchNum == Y[j])  
22:                      {  
23:                           if(searchNum == Y[start])  
24:                           {  
25:                                solution =-1;  
26:                                break;  
27:                           }  
28:                           solution++;  
29:                           //j++;                                                
30:                      }  
31:                      start = j;       
32:                 }  
33:                 result.push_back(solution);  
34:            }  
35:            return result;  
36:       }  
37:  };  


Problem Statement  1000P

     In this problem, all strings consist of uppercase English letters only. That is, there are 26 distinct letters.

The weight of a string S can be computed as follows: for each letter that occurs at least once in S, its leftmost and rightmost occurrences L and R are found and the weight is increased by R-L.

For example, if S="ABCACAZ", the weight of S is (5-0) + (1-1) + (4-2) + (6-6) = 7. (The leftmost occurrence of 'A' is at the index L=0, the rightmost one is at R=5, so 'A' contributes 5-0 = 5 to the weight of S. The only 'B' contributes 0, the pair of 'C's adds 2, and the only 'Z' adds 0.)

You are given a int L. Consider all strings of length L. Compute the weight of each of these strings. The strings with the minimum weight among all of them are called light. Your task is to count the number of light strings of length L. Since this count may be very large, return it modulo 1,000,000,009.

Definition

    
Class: StringWeightDiv2
Method: countMinimums
Parameters: int
Returns: int
Method signature: int countMinimums(int L)
(be sure your method is public)
    

Constraints

- L will be between 1 and 1000, inclusive.

Examples

0)
    
1
Returns: 26
Any string of length 1 has weight equal to 0.
1)
    
2
Returns: 650
We can divide strings of length 2 into two classes: the strings with distinct first and second letter, and the strings with two equal letters. The strings composed of two equal letters have weight 1. All the other strings have weight 0. Thus, the number of strings of minimum weight is 26*26-26=650.
2)
    
50
Returns: 488801539

       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.  

[Thoughts]  
这题就是一个排列组合题。
首先当L<=26的时候,毫无疑问,最小的字符串就是由不同的字符构成的,权重为0,那么等价于在26个字符中,挑L个进行组合,结果就是P(26,L) = (26!)/(L!).  (P是指排列数)

那么当L>26的时候呢?我们可以把问题缩小规模,来看看规律。

假设当前问题是,给定{a,b,c}三种字符,问当L=4的时候,权重最小的字符串有哪些?
我们已经知道L=3的时候,最小的字符有6个:
ABC
ACB
BAC
BCA
CAB
CBA
现在要再加一个字符,怎么加?以ABC为例,无论再加一个什么字符,这个字符都得和同样的字符在一起才能获得最小权重,这个很容易理解,因为同类的放在一起,right-left是最小的。那么ABC的衍生就有
AABC 权重1
ABBC 权重1
ABCC 权重1

同理推导其他最小权重字符的时候,都适用同样的规则,即同样的字符放在一起,最终的权重是最小的。

这样,问题就简单了,对于任意L的长度,我们把它切成26段,每一段赋给一个独立的字符就好了,那么这种排列组合共有多少个呢?

如上图,把L长度的字符串切成26段,这就意味着在(L-1)个空挡中挑出25个来插入分界符, 有C(L-1, 25)种可能(C是指组合数),对于26段,每段给一个字符的话,有P(26,26)种排列方式,所以这样的排列组合数共有

C(L-1, 25) * P(26, 26) = (L-1)!/(  (L-26)! *  (25!) )  * 26! = P(L-1, 25) *26

这里之所以要做这一步转换的原因,是为了避免处理基于余数的除法。组合数是带除法的,而排列数仅是乘法,实现简单。

[Code]
1:  int mod = 1000000009;  
2:  class StringWeightDiv2  
3:  {  
4:  public:  
5:       long Permutation(int n, int m)  
6:       {  
7:            long result=1;  
8:            for(int i =0; i< m; i++)  
9:            {  
10:                 result*=n;  
11:                 result%=mod;  
12:                 n--;  
13:            }  
14:            return result;  
15:       }  
16:       int countMinimums(int L)  
17:       {  
18:            if(L<=26) return Permutation(26, L);  
19:            else  
20:                 return Permutation(L-1, 25)*26%mod;  
21:       }  
22:  };  












Saturday, June 8, 2013

[TopCoder] SRM 581 DIV 2, 250p, 500p, 1000p, Solution

250P

Problem Statement

     Manao has N cards arranged in a sequence. He numbered them from left to right with numbers from 0 to N-1. Each card is colored black on one side and white on the other. Initially, each of the cards may lie on a different side. That is, some of the cards (possibly none or all of them) will be black side up and others will be white side up. Manao wants to flip some cards over to obtain an alternating configuration: every pair of successive cards must be of different colors.

You are given a string cardFront consisting of N characters. For each i, character i of cardFront is 'B' if card i lies black side up, and 'W' otherwise. Count and return the minimum number of cards which must be flipped to obtain an alternating configuration.

Definition

    
Class: BlackAndWhiteSolitaire
Method: minimumTurns
Parameters: string
Returns: int
Method signature: int minimumTurns(string cardFront)
(be sure your method is public)
    

Constraints

- cardFront will be between 3 and 50 characters long, inclusive.
- Each character in cardFront will be either 'B' or 'W'.

Examples

0)
    
"BBBW"
Returns: 1
The first three cards lie with their black side up and the fourth card lies with its white side up. Flipping the second card will give us the alternating configuration "BWBW".
1)
    
"WBWBW"
Returns: 0
The cards already form an alternating configuration.
2)
    
"WWWWWWWWW"
Returns: 4
Manao only needs to flip 4 cards to make the alternating configuration "WBWBWBWBW".
3)
    
"BBWBWWBWBWWBBBWBWBWBBWBBW"
Returns: 10

       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.  

[Thought]
很简单,题目只有两种模式“BWBWBW..."或者“WBWBWB....”,对于两种模式各做一次统计,然后取最小值即可。


[Code]
1:  #include <string>  
2:  using namespace std;  
3:  class BlackAndWhiteSolitaire  
4:  {  
5:  public:  
6:  int minimumTurns(string cardFront);  
7:  };  
8:  int BlackAndWhiteSolitaire::minimumTurns(string cardFront)  
9:  {  
10:       int len = cardFront.size();  
11:       int turn1 =0, turn2 =0;  
12:       string sample1 = "BW";  
13:       string sample2 = "WB";  
14:       for(int i =0; i< len; i++)  
15:       {  
16:            if(sample1[i%2] != cardFront[i])  
17:                 turn1++;  
18:            if(sample2[i%2] != cardFront[i])  
19:                 turn2++;  
20:       }  
21:       return min(turn1, turn2);  
22:  }  


500P

Problem Statement

     There is a long narrow storehouse. The storehouse is divided into a sequence of N identical sectors, labeled 0 through N-1. Each sector is large enough to contain a single container. Currently, some sectors are empty and some sectors are filled by containers. The storehouse also contains a surveillance system that is described below.

We are going to break into the storehouse. As a part of preparation for the heist, we already found out some information about the warehouse. In particular, we know exactly how the containers are currently placed in the warehouse. You are given a String containers consisting of N characters. For each i, character i of containers is 'X' if sector i contains a container, and it is '-' if sector i is empty.

We also discovered some information about the surveillance system. The system consists of several hidden cameras. You are given a int L with the following meaning: Each of the cameras monitors exactly L consecutive sectors. The segments of sectors monitored by different cameras might overlap, but no two cameras watch exactly the same segment. (In other words, each sector may be monitored by multiple cameras, but each camera monitors a different set of consecutive sectors.)

Finally, we know something about what the cameras currently see. You are given a int[] reports. Each element of reports corresponds to one of the cameras (in no particular order). More precisely, reports[i] is the number of containers stored in the sectors monitored by the corresponding camera.

It is guaranteed that all our information is correct and consistent.

Your task is to use the provided information to deduce which sectors are monitored by at least one surveillance camera. Return a String containing N characters. For each i, character i of the return value should be one of '+', '?', and '-'. Character '+' represents that sector i is certainly monitored by at least one camera. Character '-' represents that sector i is certainly not monitored by any of the cameras. Character '?' represents the remaining case: given the information we have, it is possible that sector i is monitored, but it is also possible that it is not monitored.

Definition

    
Class: SurveillanceSystem
Method: getContainerInfo
Parameters: String, int[], int
Returns: String
Method signature: String getContainerInfo(String containers, int[] reports, int L)
(be sure your method is public)
    

Constraints

- containers will contain N elements, where N is between 1 and 50, inclusive.
- Each character in containers will be either 'X' or '-'.
- L will be between 1 and N, inclusive.
- reports will contain between 1 and N-L+1 elements, inclusive.
- Each element of reports will be between 0 and L, inclusive.
- The given information will be consistent.

Examples

0)
    
"-X--XX"
{1, 2}
3
Returns: "??++++"
This storehouse has 6 sectors. There are containers in sectors 1, 4, and 5. There are two cameras: camera #0 monitors 1 container, and camera #1 monitors 2 containers. Clearly, camera #1 must be watching sectors 3, 4, and 5. Camera #0 may be watching sectors (0, 1, 2), (1, 2, 3), or (2, 3, 4). Thus, camera #0 is surely monitoring sector 2. Sectors 0 and 1 may or may not be monitored.
1)
    
"-XXXXX-"
{2}
3
Returns: "???-???"
The camera is monitoring either the leftmost or the rightmost segment, thus the middle sector is surely not under surveillance.
2)
    
"------X-XX-"
{3, 0, 2, 0}
5
Returns: "++++++++++?"
We can deduce that cameras #1 and #3 are watching segments (0, 1, 2, 3, 4) and (1, 2, 3, 4, 5). Camera #2 is monitoring the segment (4, 5, 6, 7, 8), since this is the only segment with two occupied sectors. Camera #0 is either watching (5, 6, 7, 8, 9) or (6, 7, 8, 9, 10), thus the rightmost sector might have slipped from the surveillance.
3)
    
"-XXXXX---X--"
{2, 1, 0, 1}
3
Returns: "???-??++++??"
4)
    
"-XX--X-XX-X-X--X---XX-X---XXXX-----X"
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}
7
Returns: "???++++?++++++++++++++++++++??????--"

       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.

[Thoughts]
这道500分的题挺直观。其实就是一个概率覆盖的问题。

首先对于输入字符串,进行一次预处理。统计下来,对于任意[i, i+L)区间内,有多少container。

然后处理camera信息,统计对于每一个监控数量i的出现次数。以测试用例3 为例,监控数量为1的camera共有两个,这就意味这,有两个不相同的区间只包含一个container, 那么在输入字符串中,我们可以发现有如下四个区间只包含一个container,我们将每个区间值都标识为1,表示出现一次。

- X X X X X - - - X - -
                  1 1 1
                        1 1 1
                           1 1 1
                              1 1 1
-------------------------------
                  1 1 2 2 3 2 1
在此,将出现概率加和,可以发现,如果四个区间里面选两个出来的话,只有出现概率>(4-2) (抽屉原理)的container才会必然被监控到。

假设D[K]表示,输入字符串中包含K个container的区间数量,那么处理camera的条件只有两个, 对于任意监控数量K
1. 如果K>= D[K], 那么将所有包含K个container的区间置为‘+’
2. 如果K<D[K],即如上例,那么将所有出现概率>(D[K]-K)的位置置为‘+’,其余位置置为'?'

[Code]  
1:  #include <vector>  
2:  #include <string>  
3:  #include <map>  
4:  #include <bitset>  
5:  using namespace std;  
6:  class SurveillanceSystem  
7:  {  
8:      public:  
9:      string getContainerInfo(string containers, vector <int> reports, int L)  
10:      {  
11:        sort(reports.begin(), reports.end());                 
12:                 string target(containers.size(), '-');  
13:                 map<int, vector<int> > lengthDir;  
14:                 int pre=0, cur = 0, count=0; //two-pointer scan  
15:                 for(int i =0; i<L; i++)  
16:                 {  
17:                      if(containers[i] =='X')  
18:                           count++;  
19:                      pre++;  
20:                 }  
21:                 vector<int>* dir = &lengthDir[count];  
22:                 dir->push_back(cur);                 
23:                 while(pre< containers.size())  
24:                 {                      
25:                      if(containers[pre] == 'X')  
26:                           count++;  
27:                      if(containers[cur] == 'X')  
28:                           count--;  
29:                      pre++;  
30:                      cur++;  
31:                      vector<int>* dir = &lengthDir[count];  
32:                      dir->push_back(cur);  
33:                 }  
34:                 bitset<51> doubtless, doubt;                 
35:                 int expectCount;  
36:                 int report;  
37:                 for(int length =0; length<reports.size(); length++)  
38:                 {  
39:                      expectCount=1;  
40:                      report = reports[length];  
41:                      while(length<reports.size()-1 && reports[length] == reports[length+1])  
42:                      {  
43:                           expectCount++;  
44:                           length++;  
45:                      }  
46:                      if(expectCount < lengthDir[report].size())// for exmple, expect 1 camera watching 3 storages, but there are muiltiple choice  
47:                      {  
48:                           int counter[51];  
49:                           memset(counter, 0, sizeof(counter));                           
50:                           for(int k =0; k< lengthDir[report].size(); k++ )  
51:                           {  
52:                                for(int j =0; j<L; j++)  
53:                                {  
54:                                     counter[lengthDir[report][k] +j] ++;  
55:                                }                                
56:                           }  
57:                           for(int k =0; k< target.size(); k++)  
58:                           {  
59:                                if(counter[k] ==0) continue;  
60:                                if(expectCount > lengthDir[report].size() - counter[k])  
61:                                     doubtless.set(k,1);  
62:                                else  
63:                                     doubt.set(k,1);  
64:                           }                 
65:                      }  
66:                      else  
67:                      {                           
68:                           for(int k =0; k< lengthDir[report].size(); k++ )  
69:                           {  
70:                                for(int j =0; j<L; j++)  
71:                                {  
72:                                     doubtless.set(lengthDir[report][k]+j,1);  
73:                                }                                
74:                           }                      
75:                      }                      
76:                 }  
77:                 for(int i =0; i< target.size();i++)  
78:                 {  
79:                      if(doubtless[i] ==1)  
80:                           target[i] ='+';  
81:                      else if(doubt[i] ==1)  
82:                           target[i] ='?';  
83:                 }  
84:                 return target;  
85:      }                
86:  };  



1000P

Problem Statement

     This problem statement contains superscripts and/or subscripts. These may not display properly outside the applet.

Manao is studying graph theory and simple cycles in particular. A simple cycle of length L ≥ 3 in graph G is a sequence of vertices (v0, v1, ..., vL-1) such that all v0, v1, ..., vL-1 are pairwise distinct and for each i=0..L-1, an edge between vi and v(i+1) mod L exists in G.

Manao is interested in graphs formed by connecting two trees. The connection process is as follows. Manao takes two trees composed of N vertices each. The vertices in each tree are labeled from 0 to N - 1. Then, he generates some permutation P of numbers from 0 to N - 1. Finally, the graph is formed by connecting vertex i of the first tree to vertex P[i] of the second tree, for each i from 0 to N - 1. To remove ambiguity, the vertices of the first tree within the graph are referred to as A0, A1, ..., AN-1 and the vertices of the second graph are referred to as B0, B1, ..., BN-1. Manao wants to know the maximum number of simple cycles of length K which the resulting graph could contain if he chooses P optimally.

You are given two String[]s, tree1 and tree2. Both contain N elements, each of them N characters long. The j-th character in the i-th element of tree1 is 'X' if vertices i and j in the first tree are connected and '-' otherwise. tree2 describes the second tree in the same fashion.

Compute and return the maximum possible number of simple cycles of length K in the graph formed by connecting the two given trees as described above. Two simple cycles are equal if one of them can be cyclically shifted, or reversed and cyclically shifted, to coincide with the second. According to this definition, (1, 2, 3, 4), (2, 3, 4, 1) and (3, 2, 1, 4) are all equal.

Definition

    
Class: TreeUnionDiv2
Method: maximumCycles
Parameters: String[], String[], int
Returns: int
Method signature: int maximumCycles(String[] tree1, String[] tree2, int K)
(be sure your method is public)
    

Constraints

- tree1 and tree2 will each contain N elements, where N is between 1 and 9, inclusive.
- Each element of tree1 and tree2 will be N characters long.
- Each element of tree1 and tree2 will consist of 'X' and '-' characters only.
- tree1[i][i] and tree2[i][i] will be '-' for each i between 0 and N-1.
- tree1[i][j] will be equal to tree1[j][i] for each i, j between 0 and N-1.
- tree2[i][j] will be equal to tree2[j][i] for each i, j between 0 and N-1.
- Both tree1 and tree2 will describe a graph which is a tree.
- K will be between 3 and 7, inclusive.

Examples

0)
    
{"-X",
 "X-"}
{"-X",
 "X-"}
4
Returns: 1
Manao has two trees with two vertices each. He can connect them in two ways:



Either way, the resulting graph is a single cycle of length 4.
1)
    
{"-X-",
 "X-X",
 "-X-"}
{"-X-",
 "X-X",
 "-X-"}
5
Returns: 2
These are the possible six graphs which can be obtained by connecting the two given trees:



Except for the two topmost graphs, all the graphs contain two cycles of length 5.
2)
    
{"-X-",
 "X-X",
 "-X-"}
{"-X-",
 "X-X",
 "-X-"}
3
Returns: 0
These are the same trees as in the previous example. You can see at the pictures that none of the obtained graphs contains a cycle of length 3.
3)
    
{"-X---",
 "X-XXX",
 "-X---",
 "-X---",
 "-X---"}
{"-X-X-",
 "X-X-X",
 "-X---",
 "X----",
 "-X---"}
6
Returns: 5
When the permutation P is {0, 3, 2, 1, 4}, the resulting graph contains the following five simple cycles of length 6:
  • A0, A1, A4, B4, B1, B0
  • A0, A1, A2, B2, B1, B0
  • A1, A2, B2, B1, B0, B3
  • A1, A2, B2, B1, B4, A4
  • A1, A4, B4, B1, B0, B3
The corresponding graph is the following:

4)
    
{"-XX------",
 "X------X-",
 "X--XX-X--",
 "--X--X---",
 "--X------",
 "---X----X",
 "--X------",
 "-X-------",
 "-----X---"}

{"-X-------",
 "X-X------",
 "-X-XX----",
 "--X---X--",
 "--X--X---",
 "----X--XX",
 "---X-----",
 "-----X---",
 "-----X---"}
7
Returns: 17

       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.    


[Thoughts]
还没做


















Saturday, June 1, 2013

[TopCoder] SRM580, DIV1, 600p, Solution


Problem Statement

     A group of freshman rabbits has recently joined the Eel club. No two of the rabbits knew each other. Yesterday, each of the rabbits went to the club for the first time. For each i, rabbit number i entered the club at the time s[i] and left the club at the time t[i].
Each pair of rabbits that was in the club at the same time got to know each other, and they became friends on the social network service Shoutter. This is also the case for rabbits who just met for a single moment (i.e., one of them entered the club exactly at the time when the other one was leaving).
In Shoutter, each user can post a short message at any time. The message can be read by the user's friends. The friends can also repost the message, making it visible to their friends that are not friends with the original poster. In turn, those friends can then repost the message again, and so on. Each message can be reposted in this way arbitrarily many times. If a rabbit wants to repost multiple messages, he must repost each of them separately.
Today, each of the rabbits posted a self-introduction to Shoutter. Each rabbit would now like to read the self-introductions of all other rabbits (including those that are currently not his friends). Compute and return the minimal number of reposts necessary to reach this goal. If it is impossible to reach the goal, return -1 instead.
As the number of rabbits can be greater than what the TopCoder arena supports, you are given the times s[i] and t[i] encoded in the following form: You are given vector <string>s s1000, s100, s10, and s1. Concatenate all elements of s1000 to obtain a string S1000. In the same way obtain the strings S100, S10, and S1. Character i of each of these strings corresponds to the rabbit number i. More precisely, these characters are the digits of s[i]: we obtain s[i] by converting the string S1000[i]+S100[i]+S10[i]+S1[i] to an integer. For example, if S1000[4]='0', S100[4]='1', S10[4]='4', and S1[4]='7', then s[4]=to_integer("0147")=147. You are also given vector <string>s t1000, t100, t10, and t1. These encode the times t[i] in the same way.

Definition

    
Class: ShoutterDiv1
Method: count
Parameters: vector <string>, vector <string>, vector <string>, vector <string>, vector <string>, vector <string>, vector <string>, vector <string>
Returns: int
Method signature: int count(vector <string> s1000, vector <string> s100, vector <string> s10, vector <string> s1, vector <string> t1000, vector <string> t100, vector <string> t10, vector <string> t1)
(be sure your method is public)
    

Constraints

- s1000, s100, s10, s1, t1000, t100, t10 and t1 will each contain between 1 and 50 elements, inclusive.
- s1000, s100, s10, s1, t1000, t100, t10 and t1 will contain the same number of elements.
- Each element of s1000, s100, s10, s1, t1000, t100, t10 and t1 will contain between 1 and 50 characters, inclusive.
- For each i, the i-th elements of all input variables will all contain the same number of characters.
- Each character in the input variables will be a digit ('0'-'9').
- For each i, t[i] will be greater than or equal to s[i].

Examples

0)
    
{"22", "2"}
{"00", "0"}
{"11", "1"}
{"21", "4"}
{"22", "2"}
{"00", "0"}
{"11", "1"}
{"43", "6"}
Returns: 2
After parsing the input, you will get the following information: Rabbit 0 will enter the room at 2012 and leave the room at 2014. Rabbit 1 will enter the room at 2011 and leave the room at 2013. Rabbit 2 will enter the room at 2014 and leave the room at 2016. Therefore, Rabbit 0 and Rabbit 1 will be friends, and Rabbit 0 and Rabbit 2 will be friends too, but Rabbit 1 and Rabbit 2 won't be friends.

Rabbit 0 can already see the self-introductions of all rabbits, but rabbits 1 and 2 cannot see each other's self-introduction. Two actions are needed: First, Rabbit 0 reposts the self-introduction of Rabbit 1, and then Rabbit 0 reposts the self-introduction of Rabbit 2. Now everybody can read everything.
1)
    
{"00"}
{"00"}
{"00"}
{"13"}
{"00"}
{"00"}
{"00"}
{"24"}
Returns: -1
If it is impossible to achieve the goal, return -1.
2)
    
{"0000"}
{"0000"}
{"0000"}
{"1234"}
{"0000"}
{"0000"}
{"0000"}
{"2345"}
Returns: 6
The following pairs will be friends: Rabbit 0 and 1, 1 and 2, and 2 and 3. One of the optimal strategies is as follows:
  • Rabbit 1 shares introductions of Rabbit 0 and 2.
  • Rabbit 2 shares introductions of Rabbit 1 and 3.
  • Rabbit 1 shares introduction of Rabbit 3 (this is possible because now Rabbit 3's introduction is shared by Rabbit 2, who is a Rabbit 1's friend).
  • Rabbit 2 shares introduction of Rabbit 0 (this is possible because now Rabbit 0's introduction is shared by Rabbit 1, who is a Rabbit 2's friend).
3)
    
{"0000000000"}
{"0000000000"}
{"0000000000"}
{"7626463146"}
{"0000000000"}
{"0000000000"}
{"0000000000"}
{"9927686479"}
Returns: 18
4)
    
{"00000000000000000000000000000000000000000000000000"}
{"00000000000000000000000000000000000000000000000000"}
{"50353624751857130208544645495168271486083954769538"}
{"85748487990028258641117783760944852941545064635928"}
{"00000000000000000000000000000000000000000000000000"}
{"00000000000000000000000000000000000000000000000000"}
{"61465744851859252308555855596388482696094965779649"}
{"37620749792666153778227385275518278477865684777411"}
Returns: 333

       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.  


[Thoughts]
第三组测试数据比较有代表性,以此作为分析样例,如下图















Robbit                         好友列表
0                                 1,2,3,4
1                                 0
2                                 0,3,4,5,6,7,8
3                                 0,2,4,5,6,7,8,9
4                                 0,2,3,5,6,7,8
5                                 2,3,4,6,7,8,9
6                                 2,3,4,5,7,8,9
7                                 2,3,4,5,6,8,9
8                                 2,3,4,5,6,7,9
9                                 3,5,6,7,8

对于Robbit 0,当它发出个人介绍以后,Set = {1,2,3,4}都会收到,那么下一步只需要通过3 RePost,那么Set = {1,2,3,4} U {0,2,4,5,6,7,8,9} = {0,1,2,3,4,5,6,7,8,9},所有人至此都收到了Robbit 0的介绍。所以,Robbit 0 只需要repost 1次。

对于Robbit 1,比较复杂,因为它只有一个好友,当它发出个人介绍以后,接收者Set = {0}, 然后Robbit 0 repost Robbit 1的个人介绍一次, Set = {0} U {1,2,3,4} = {0,1,2,3,4}, 然后需要Robbit 3再repost一次到所有的Robbit,Set = {0,1,2,3,4} U {0,2,4,5,6,7,8,9}。所以,Robbit 1需要2 次。

对于Robbit2,第一次post,Set = {0,3,4,5,6,7,8}, 需要在Robbit 0 Repost一次到Robbit1,需要在Robbit 5处Repost一次到Robbit 9. 共计 2次

再比如Robbit 5, 第一次Post, Set = {2,3,4,6,7,8,9}, 需要在Robbit 2处Repost一次到Robbit 0, 然后需要在Robbit 0处Repost一次到Robbit 1, 共计2次

同理可以推导出,
Robbit                                   Repost Num
0                                           1
1                                           2
2                                           2
3                                           1
4                                           2
5                                           2
6                                           2
7                                           2
8                                           2
9                                           2

总计18次。

所以,这个就是图的最小覆盖问题。从一个节点出发,覆盖整个图最少需要走多少步。然后遍历每一个节点,将步数求和即可。

有个简单的实现,基于bitset来做。


Main Logic
1:  #include <string>  
2:  #include <vector>  
3:  #include <bitset>  
4:  using namespace std;  
5:  class ShoutterDiv1  
6:  {  
7:  public:  
8:       int count(vector<string> s1000,vector<string> s100,vector<string> s10,vector<string> s1,vector<string> t1000,vector<string> t100,vector<string> t10,vector<string> t1);  
9:  };  
10:  int s[3000], t[3000];  
11:  int ShoutterDiv1::count(vector<string> s1000,vector<string> s100,vector<string> s10,vector<string> s1,vector<string> t1000,vector<string> t100,vector<string> t10,vector<string> t1)  
12:  {  
13:       int len = s1000.size();  
14:       for(int i=1; i< len; i++)  
15:       {  
16:            s1000[0] +=s1000[i];  
17:            s100[0] +=s100[i];  
18:            s10[0] +=s10[i];  
19:            s1[0] +=s1[i];  
20:            t1000[0] +=t1000[i];  
21:            t100[0] +=t100[i];  
22:            t10[0] +=t10[i];  
23:            t1[0] +=t1[i];            
24:       }  
25:       len = s1000[0].size();       
26:       for(int i =0; i< len; i++)  
27:       {  
28:            s[i] = (s1000[0][i]-'0')*1000 + (s100[0][i]-'0')*100 +(s10[0][i]-'0')*10 +(s1[0][i]-'0');  
29:            t[i] = (t1000[0][i]-'0')*1000 + (t100[0][i]-'0')*100 +(t10[0][i]-'0')*10 +(t1[0][i]-'0');  
30:       }  
31:       vector<bitset<3000> > firstConnection;  
32:       for(int i =0; i< len; i++)  
33:       {  
34:            bitset<3000> friends(0);  
35:            for(int j=0; j< len; j++)  
36:            {  
37:                 if(min(t[i],t[j]) - max(s[i], s[j])>=0)  
38:                 {  
39:                      friends.set(j,1);  
40:                 }  
41:            }  
42:            firstConnection.push_back(friends);  
43:       }  
44:       int count=0;  
45:       for(int i =0; i< len; i++)  
46:       {  
47:            bitset<3000> connections(0);            
48:            connections = connections | firstConnection[i];  
49:            if(connections.count() == len) // already arrive all Robbits  
50:            {  
51:                 continue;  
52:            }            
53:            while(true)  
54:            {  
55:                 bitset<3000> left = connections;  
56:                 left.flip();  
57:                 int bestChoice=-1, coveredNum=0;  
58:                 for(int j =0; j< len; j++)  //greedy. Find the largest override
59:                 {  
60:                      if(!connections[j]) continue;  
61:                      bitset<3000> result = left & firstConnection[j];  
62:                      if(result.count() > coveredNum)  
63:                      {  
64:                           coveredNum = result.count();  
65:                           bestChoice = j;  
66:                      }                      
67:                 }  
68:                 if(bestChoice == -1) //No new Friends found  
69:                 {  
70:                      return -1;  
71:                 }                 
72:                 connections = connections | firstConnection[bestChoice];                 
73:                 count++;  
74:                 if(connections.count() == len) // already arrive all Robbits  
75:                 {  
76:                      break;  
77:                 }  
78:            }  
79:       }  
80:       return count;       
81:  }  



Saturday, May 25, 2013

[TopCoder] SRM 580 DIV 2, 250p, 500p, 1000p, Solution

250 points

Problem Statement

     A group of freshman rabbits has recently joined the Eel club. No two of the rabbits knew each other. Today, each of the rabbits went to the club for the first time. You are given vector <int>s s and t with the following meaning: For each i, rabbit number i entered the club at the time s[i] and left the club at the time t[i].
Each pair of rabbits that was in the club at the same time got to know each other, and they became friends on the social network service Shoutter. This is also the case for rabbits who just met for a single moment (i.e., one of them entered the club exactly at the time when the other one was leaving).
Compute and return the number of pairs of rabbits that became friends today.

Definition

    
Class: ShoutterDiv2
Method: count
Parameters: vector <int>, vector <int>
Returns: int
Method signature: int count(vector <int> s, vector <int> t)
(be sure your method is public)
    

Constraints

- s and t will contain between 1 and 50 integers, inclusive.
- s and t will contain the same number of elements.
- Each integer in s and t will be between 0 and 100, inclusive.
- For each i, t[i] will be greater than or equal to s[i].

Examples

0)
    
{1, 2, 4}
{3, 4, 6}
Returns: 2
Rabbit 0 and Rabbit 1 will be friends because both of them are in the club between time 2 and 3.
Rabbit 0 and Rabbit 2 won't be friends because Rabbit 0 will leave the club before Rabbit 2 enters the club.
Rabbit 1 and Rabbit 2 will be friends because both of them are in the club at time 4.
1)
    
{0}
{100}
Returns: 0
2)
    
{0,0,0}
{1,1,1}
Returns: 3
3)
    
{9,26,8,35,3,58,91,24,10,26,22,18,15,12,15,27,15,60,76,19,12,16,37,35,25,4,22,47,65,3,2,23,26,33,7,11,34,74,67,32,15,45,20,53,60,25,74,13,44,51}
{26,62,80,80,52,83,100,71,20,73,23,32,80,37,34,55,51,86,97,89,17,81,74,94,79,85,77,97,87,8,70,46,58,70,97,35,80,76,82,80,19,56,65,62,80,49,79,28,75,78}
Returns: 830

       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.

[Thoughts]
简单的计算区间重合。对于任意两个区间A和B,存在以下四种重合情况:
1. A与B左部重合
2. A与B右部重合
3. A包括B
4. B包括A

假设A的区间是(s[i], t[i]), 而B的区间为(s[j],t[j]),那么重合的判断式如下:
if((s[j] >= s[i] && S[j]<=t[i]) || (t[j]>=s[i] && t[j]<=t[i]) || (s[i] < s[j] && t[i] > t[j]) || (s[i]>s[j] && t[i] < t[j]))
{
count++;
}

显然,这个公式太长了,可以用如下简写版替代:
if( min(t[i],t[j]) - max(s[i], s[j]) ) >==0


[Code]

1:  #include <vector>  
2:  using namespace std;  
3:  class ShoutterDiv2  
4:  {  
5:       public:  
6:       int count(vector <int> s, vector <int> t);  
7:  };  
8:  int ShoutterDiv2::count(vector <int> s, vector <int> t)  
9:  {  
10:       int count=0;  
11:       for(int i =0; i< s.size()-1; i++)  
12:       {  
13:            for(int j =i+1; j< s.size(); j++)  
14:            {  
15:                 if(min(t[i],t[j]) - max(s[i], s[j])>=0)  
16:                 {  
17:                      count++;  
18:                 }  
19:            }  
20:       }  
21:       return count;  
22:  }  

  

500 points

Problem Statement

     Rabbit went to a river to catch eels. All eels are currently swimming down the stream at the same speed. Rabbit is standing by the river, downstream from all the eels.

Each point on the river has a coordinate. The coordinates increase as we go down the stream. Initially, Rabbit is standing at the origin, and all eels have non-positive coordinates.

You are given two vector <int>s: l and t. These describe the current configuration of eels. The speed of each eel is 1 (one). For each i, the length of eel number i is l[i]. The head of eel number i will arrive at the coordinate 0 precisely at the time t[i]. Therefore, at any time T the eel number i has its head at the coordinate T-t[i], and its tail at the coordinate T-t[i]-l[i].

Rabbit may only catch an eel when some part of the eel (between head and tail, inclusive) is at the same coordinate as the rabbit. Rabbit can catch eels at most twice. Each time he decides to catch eels, he may catch as many of the currently available eels as he wants. (That is, he can only catch eels that are in front of him at that instant, and he is allowed and able to catch multiple eels at once.)

Return the maximal total number of eels Rabbit can catch.

Definition

    
Class: EelAndRabbit
Method: getmax
Parameters: vector <int>, vector <int>
Returns: int
Method signature: int getmax(vector <int> l, vector <int> t)
(be sure your method is public)
    

Constraints

- l will contain between 1 and 50 elements, inclusive.
- Each element of l will be between 1 and 1,000,000,000, inclusive.
- l and t will contain the same number of elements.
- Each element of t will be between 0 and 1,000,000,000, inclusive.

Examples

0)
    
{2, 4, 3, 2, 2, 1, 10}
{2, 6, 3, 7, 0, 2, 0}
Returns: 6
Rabbit can catch 6 eels in the following way:
  • At time 2, catch Eel 0, Eel 4, Eel 5, and Eel 6.
  • At time 8, catch Eel 1 and Eel 3.
1)
    
{1, 1, 1}
{2, 0, 4}
Returns: 2
No two eels are in front of Rabbit at the same time, so Rabbit can catch at most two eels.
2)
    
{1}
{1}
Returns: 1
3)
    
{8, 2, 1, 10, 8, 6, 3, 1, 2, 5}
{17, 27, 26, 11, 1, 27, 23, 12, 11, 13}
Returns: 7

       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.  

[Thoughts]
这一题和Leetcode里面买股票的题很类似。

将输入参数转化为Interval,对于任意鱼i,Interval[i].left = t[i], Interval[i].right = t[i]+l[i]。有了Interval数组之后,只要计算该数组在任意时间点上的重合数量,即可确定在该时间点上可以抓到多少鱼。题目已经说了,机器人最多可以抓两次鱼,所以模拟两次抓鱼即可。


[Code]

1:  #include <vector>  
2:  #include <string>  
3:  using namespace std;  
4:  class EelAndRabbit  
5:  {  
6:  public:  
7:       int getmax(vector <int> l, vector <int> t);  
8:       int GetFish(vector <int>& l, vector <int>& t, int time, vector<int>& visited, bool isSecond);  
9:  };  
10:  int EelAndRabbit::getmax(vector <int> l, vector <int> t)  
11:  {  
12:       vector<int> visited(t.size());  
13:       int maxCatch=0;  
14:       for(int i =0;i<t.size(); i++) // t is the left boundary of interval, and l will be right boundary  
15:       {  
16:            l[i] = l[i] +t[i];  
17:       }       
18:       for(int i =0; i< t.size(); i++)  
19:       {  
20:            std::fill(visited.begin(), visited.end(),0);  
21:            int firstCatch = GetFish(l,t, t[i], visited,false); //first catch  
22:            int secondCatch=0;  
23:            for(int j=0;j<t.size(); j++)  
24:            {  
25:                 if(j== i || t[i]>t[j]) continue;                 
26:                 int temp = GetFish(l,t, t[j], visited,true); //second catch  
27:                 if(temp>secondCatch) secondCatch = temp;  
28:            }  
29:            if((firstCatch+secondCatch) >maxCatch)  
30:            {  
31:                 maxCatch=firstCatch+secondCatch;            
32:            }            
33:       }       
34:       return maxCatch;  
35:  }  
36:  int EelAndRabbit::GetFish(vector <int>& l, vector <int>& t, int time, vector<int>& visited, bool isSecond)  
37:  {  
38:       int temp=0;  
39:       for(int i =0; i< t.size(); i++)  
40:       {  
41:            if(visited[i]) continue; //fish had been caught in first round.            
42:            if((time >= t[i] && time<=l[i]))  // find the overlap interval
43:            {  
44:                 if(!isSecond) visited[i] =1;  
45:                 temp++;  
46:            }            
47:       }  
48:       return temp;  
49:  }  



1000 points

Problem Statement

     Rabbit and Eel are playing a board game. The game is played with a single token on a rectangular board that is divided into a grid of unit cells. Some cells contain a digit that represents the cost of placing the token onto that cell. Other cells contain the letter 'x' that represents a blocked cell. It is not allowed to place the token onto a blocked cell.
Initially, the token is placed on the leftmost cell of the topmost row. (The constraints guarantee that this cell will never be blocked and its cost will always be 0.) Eel starts the game by putting up some walls. Eel may place as many walls as he wants, including none. Each wall must be placed between two adjacent cells in the same column.
Once Eel has placed the walls, Rabbit gets to move the token. In each step, Rabbit may move the token one cell left, one cell right, or one cell down. (Note that Rabbit is not allowed to move the token upwards.) Rabbit may only move the token into cells that are not blocked. Each time Rabbit moves the token into a cell, he has to pay the cost associated with that cell.
The game ends when Rabbit first moves the token into the bottommost row. The constraints guarantee that this can be achieved if Eel does not place any walls. The game must always be allowed to end. That is, Eel must not place a set of walls that blocks all possible paths to the bottommost row.
Rabbit's goal is to minimize and Eel's goal is to maximize the total cost paid by Rabbit during the game. You are given the String[] costs representing the costs of cells: character j of element i of cost is either a digit that represents the cost written in the cell in row i, column j; or it is the letter 'x' that represents a blocked cell. Return the total cost of the game assuming that both Rabbit and Eel play optimally.

Definition

    
Class: WallGameDiv2
Method: play
Parameters: String[]
Returns: int
Method signature: int play(String[] costs)
(be sure your method is public)
    

Constraints

- costs will contain between 2 and 50 elements, inclusive.
- Each element of costs will contain between 1 and 50 characters, inclusive.
- Each element of costs will contain the same number of characters.
- Each character of each element of costs will be a letter 'x' or a decimal digit ('0'-'9').
- There will be at least one valid path from the leftmost cell of topmost row to a cell in the bottommost row.
- costs[0][0] will always be '0'.

Examples

0)
    
{"042"
,"391"}
Returns: 13
Eel's optimal stategy is to put two walls: between '0'-'3' and between '2'-'1'. Then Rabbit's optimal strategy is to move the token along the path '0'->'4'->'9'. The total cost will be 13.
1)
    
{"0xxxx"
,"1x111"
,"1x1x1"
,"11191"
,"xxxx1"}
Returns: 16
There's only one path from the starting cell to the bottom row and Eel isn't allowed to block it. Rabbit will move the token along this path and will get to pay a cost of 16. Note that it is not allowed to move the token upwards.
2)
    
{"0"
,"5"}
Returns: 5
3)
    
{"0698023477896606x2235481563x59345762591987823x663"
,"1x88x8338355814562x2096x7x68546x18x54xx1077xx5131"
,"64343565721335639575x18059738478x156x781476124780"
,"2139850139989209547489708x3466104x5x3979260330074"
,"15316x57171x182167994729710304x24339370252x2x8846"
,"459x479948xx26916349194540891252317x99x4329x34x91"
,"96x3631804253899x69460666282614302698504342364742"
,"4x41693527443x7987953128673046855x793298x8747219x"
,"7735427289436x56129435153x83x37703808694432026643"
,"340x973216747311x970578x9324423865921864682853036"
,"x1442314831447x860181542569525471281x762734425650"
,"x756258910x0529918564126476x481206117984425792x97"
,"467692076x43x91258xx3xx079x34x29xx916574022682343"
,"9307x08x451x2882604411x67995x333x045x0x5xx4644590"
,"4x9x088309856x342242x12x79x2935566358156323631235"
,"04596921625156134477422x2691011895x8564609x837773"
,"223x353086929x27222x48467846970564701987061975216"
,"x4x5887805x89746997xx1419x758406034689902x6152567"
,"20573059x699979871151x444449x5170122650576586x898"
,"683344308229681464514453186x51040742xx138x5170x93"
,"1219892x9407xx63107x24x4914598xx4x478x31485x69139"
,"856756530006196x8722179365838x9037411399x41126560"
,"73012x9290145x1764125785844477355xx827269976x4x56"
,"37x95684445661771730x80xx2x459547x780556228951360"
,"54532923632041379753304212490929413x377x204659874"
,"30801x8716360708478705081091961915925276739027360"
,"5x74x4x39091353819x10x433010250089676063173896656"
,"03x07174x648272618831383631629x020633861270224x38"
,"855475149124358107x635160129488205151x45274x18854"
,"091902044504xx868401923845074542x50x143161647934x"
,"71215871802698346x390x2570413992678429588x5866973"
,"87x4538137828472265480468315701832x24590429832627"
,"9479550007750x658x618193862x80317248236583631x846"
,"49802902x511965239855908151316389x972x253946284x6"
,"053078091010241324x8166428x1x93x83809001454563464"
,"2176345x693826342x093950x12x7290x1186505760xx978x"
,"x9244898104910492948x2500050208763770568x92514431"
,"6855xx7x145213846746325656963x0419064369747824511"
,"88x15690xxx31x20312255171137133511507008114887695"
,"x391503034x01776xx30264908792724712819642x291x750"
,"17x1921464904885298x58x58xx174x7x673958x9615x9230"
,"x9217049564455797269x484428813681307xx85205112873"
,"19360179004x70496337008802296x7758386170452xx359x"
,"5057547822326798x0x0569420173277288269x486x582463"
,"2287970x0x474635353111x85933x33443884726179587xx9"
,"0x697597684843071327073893661811597376x4767247755"
,"668920978869307x17435748153x4233659379063530x646x"
,"0019868300350499779516950730410231x9x18749463x537"
,"00508xx083203827x42144x147181308668x3192478607467"}
Returns: 3512

       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.  


[Thoughts]
DP
首先如果这个题只有Robbit的话,很容易发现这是一个最小路径的DP。此题巧妙处在于做了一个转换,增加了Eel,转换为双人博弈。题目中说了,Eel总是会增加阻碍,让Robbit只能走代价最高的路径。简单的说,如果Eel非常尽职的话,Robbit在每一行只能选择代价最高的那个cell,因为凡是好的路径,必然已经被Eel设置了路障。所以这个题说到底,就是最大路径的DP。具体看code。


[Code]

1:  #include <vector>  
2:  #include <string>  
3:  using namespace std;  
4:  class WallGameDiv2  
5:  {  
6:  public:  
7:       int play(vector <string> costs);  
8:  };  
9:  int cost[51][51];  
10:  int dp[51][51];  
11:  int row, col;  
12:  int WallGameDiv2::play(vector <string> costs)  
13:  {  
14:       //initialize the cost and dp array  
15:       memset(cost, -1, sizeof(cost));  
16:       memset(dp, -1, sizeof(dp));  
17:       row = costs.size();  
18:       col = costs[0].size();  
19:       for(int i =0; i< row; i++)  
20:       {  
21:            for(int j=0; j< col; j++)  
22:            {  
23:                 if(costs[i][j] != 'x')  
24:                 {  
25:                      cost[i][j] = costs[i][j]-'0';  
26:                 }  
27:            }  
28:       }  
29:       dp[0][0] =0;  
30:       //first row  
31:       for(int i =1; i< col && cost[0][i]!=-1; i++)  
32:       {  
33:            dp[0][i] = (dp[0][i-1] + cost[0][i]);  
34:       }  
35:       for(int i =1; i< row-1; i++)  
36:       {  
37:            for(int j=0; j<col; j++)  
38:            {  
39:                 if(dp[i-1][j] == -1) continue;                 
40:                 //for each cost i,j, update the value with worst cost  
41:                 int estiCost = dp[i-1][j];  
42:                 //right                 
43:                 for(int k = j; k<col && cost[i][k]!=-1; k++)  
44:                 {  
45:                      estiCost+=cost[i][k];  
46:                      dp[i][k] = max(dp[i][k], estiCost);  
47:                 }  
48:                 //left  
49:                 estiCost = dp[i-1][j];  
50:                 for(int k=j; k >=0&& cost[i][k]!=-1; k--)  
51:                 {  
52:                      estiCost+=cost[i][k];  
53:                      dp[i][k] = max(dp[i][k], estiCost);  
54:                 }  
55:            }  
56:       }  
57:       // last row is special       
58:       int steps = 0;  
59:       for(int i =0; i< col; i++)  
60:       {  
61:            if(cost[row-1][i] ==-1) continue;  
62:            steps = max(steps, dp[row-2][i]+cost[row-1][i]);  
63:       }  
64:       return steps;  
65:  }  


[Note]
Line 15 & 16
最初的写法是:
memset(cost, -1, sizeof(cost)/sizeof(int));
memset(dp, -1, sizeof(dp)/sizeof(int));
刚开始提交,过不了大数据,翻来覆去的看,也没发现有什么问题。最后拿到visual studio里面debug才发现问题,多了sizeof(int)。对于c++不是特别熟悉呀。