Running highest score algorithm (dynamic programming)-"Struggle Cup" programming contest topic

At the weekend, I participated in the "Struggle Cup" Shanghai Youth Computer Programming Competition and won the second prize. This is one of the questions, because I didn't work it out because of lack of time, the ideas were all right, and it was almost completed. Dynamic programming has always been my weakness, take this opportunity to record it.

0, title

Student A participates in a running competition, the path is divided into n sections, each section has a different score. If you don’t score for this segment of walking, you get the corresponding score for this segment of jogging; this segment of fast running gets twice the corresponding score, but you must walk for the next segment. Find the highest score that student A can get for the complete course.

If there are 4 sections in total and the corresponding scores are [1, 2, 3, 4], the running method with the highest score is to jog in the first three sections and run fast in the last section, that is, 1+2+3+4*2 = 14.

Input the array of corresponding road segment scores, and output the highest score obtained.

  • Golang
  • Java

1. Thinking

State transition, classicDynamic programmingalgorithm.

1.1 Array definition

Define a two-dimensional array dp[i][j] ,

  • The value is the highest score that can be obtained in the current state;
  • i is the index of the road segment;
  • j is the running state of this segment, when j=0 is walking, j=1 is jogging, and j=2 is fast running .

1.2 Initialization

dp[0][0] = 0
dp[0][1] = points[0]
dp[0][2] = points[0] * 2

1.3 State transition

  • If you choose to walk in this paragraph, the previous paragraph can be walking, jogging, or fast running, so dp[i][0] = max(dp[i-1][0], dp[i-1][1], dp[i-1][2])
  • If you choose jogging in this paragraph, the previous paragraph can be walking or jogging, so dp[i][1] = max(dp[i-1][0], dp[i-1][1]) + current segment score
  • If fast running is selected in this paragraph, the previous paragraph can be walking or jogging, so dp[i][2] = max(dp[i-1][0], dp[i-1][1]) + current segment score Twice

In the end, just find the largest value in dp[n-1].

1.4 Space complexity optimization

After writing dp, it is found that the final result is only related to the last result, and the previously calculated value does not need to be stored. Based on this, only need to define 3 variables to record the highest scores that can be obtained in the previous three states. Space complexity canFrom O(n) optimization to O(1)

Define prevWalk, prevSlowRun, and prevFastRun as the total highest scores obtained by walking, jogging, and fast running respectively in the previous section.
Then just transfer the state as above

2 code implementation

2.1 Go language implementation

//go语言实现
func run(points []int) int {
    
    
	length := len(points)
	if length == 0 {
    
    
		return 0
	}

	//dp[i][j]值为当前路段当前状态获得的最大总分数,i为路段的索引,j为本段状态,其中0为本段走路,1为本段慢跑,2为本段快跑
	dp := make([][3]int, length)
	dp[0][0] = 0
	dp[0][1] = points[0]
	dp[0][2] = points[0] * 2
	for i := 1; i < length; i++ {
    
    
		dp[i][0] = max(max(dp[i-1][0], dp[i-1][1]), dp[i-1][2]) //本段走路,上段可以是任何状态
		dp[i][1] = max(dp[i-1][0], dp[i-1][1]) + points[i]      //本段慢跑,上段只能是走路或者慢跑
		dp[i][2] = max(dp[i-1][0], dp[i-1][1]) + points[i]*2    //本段快跑,上段只能是走路或者慢跑
	}
	return max(max(dp[length-1][0], dp[length-1][1]), dp[length-1][2])
}

func max(a, b int) int {
    
    
	if a < b {
    
    
		return b
	}
	return a
}

2.2 Implementation of Go Language Space Complexity Optimization

func runBetter(points []int) int {
    
    
	length := len(points)
	if length == 0 {
    
    
		return 0
	}

	var prevWalk, prevSlowRun, prevFastRun = 0, points[0], points[0] * 2
	for i := 1; i < length; i++ {
    
    
		var walk, slowRun, fastRun int
		walk = max(max(prevWalk, prevSlowRun), prevFastRun) //本段走路,上段可以是任何状态
		slowRun = max(prevWalk, prevSlowRun) + points[i]    //本段慢跑,上段只能是走路或者慢跑
		fastRun = max(prevWalk, prevSlowRun) + points[i]*2  //本段快跑,上段只能是走路或者慢跑
		prevWalk = walk
		prevSlowRun = slowRun
		prevFastRun = fastRun
	}
	return max(max(prevWalk, prevSlowRun), prevFastRun)
}

func max(a, b int) int {
    
    
	if a < b {
    
    
		return b
	}
	return a
}

2.3 java implementation

public static int run(int[] points){
    
    
    int n = points.length;
    if (n == 0){
    
    
        return 0;
    }
    //dp[i][j]值为当前路段当前状态获得的最大总分数,i为路段的索引,j为本段状态,其中0为本段走路,1为本段慢跑,2为本段快跑
    int[][] dp = new int[n][3];
    //初始化
    dp[0][0] = 0;
    dp[0][1] = points[0];
    dp[0][2] = points[0]*2;
    for (int i = 1; i < n; i++) {
    
    
        dp[i][0] = Math.max(Math.max(dp[i-1][0], dp[i-1][1]), dp[i-1][2]);//本段走路,上段可以是任何状态
        dp[i][1] = Math.max(dp[i-1][0],dp[i-1][1]) + points[i];     //本段慢跑,上段只能是走路或者慢跑
        dp[i][2] = Math.max(dp[i-1][0],dp[i-1][1]) + points[i] * 2; //本段快跑,上段只能是走路或者慢跑
    }
    return Math.max(Math.max(dp[n-1][0], dp[n-1][1]), dp[n-1][2]);
}

2.4 Implementation of java space complexity optimization

public static int run(int[] points){
    
    
    int n = points.length;
    if (n == 0){
    
    
        return 0;
    }
    //初始化
    int prevWalk = 0, prevSlowRun = points[0], prevFastRun = points[0] * 2;
    for (int i = 1; i < n; i++) {
    
    
        int walk = Math.max(Math.max(prevWalk, prevSlowRun), prevFastRun);//本段走路,上段可以是任何状态
        int slowRun = Math.max(prevWalk, prevSlowRun) + points[i];     //本段慢跑,上段只能是走路或者慢跑
        int fastRun = Math.max(prevWalk, prevSlowRun) + points[i] * 2; //本段快跑,上段只能是走路或者慢跑
        prevWalk = walk;
        prevSlowRun = slowRun;
        prevFastRun = fastRun;
    }
    return Math.max(Math.max(prevWalk, prevSlowRun), prevFastRun);
}

Guess you like

Origin blog.csdn.net/u012140251/article/details/109410044