HIT研究生算法作业4

1、答:
定义: m a x S u m i A [ 1 , . . . i ] ; s u m i maxSum_i为A[1,...i]连续子数组的最大和;sum_i为当前连续子数组的和 ,则有

递推方程:

s u m i = A [ i ] i f    i = 1       s u m i 1 < 0 s u m i = s u m i 1 + A [ i ] i f    s u m i 1 > = 0 m a x S u m i = A [ i ] i f    i = 1 m a x S u m i = M a x ( m a x S u m i 1 , s u m i ) sum_i = A[i] \qquad if \;i = 1\;或 \;sum_{i-1} < 0\\ sum_i = sum_{i-1} + A[i] \qquad if\; sum_{i-1} >=0\\ maxSum_i = A[i] \qquad if \; i = 1 \\ maxSum_i = Max(maxSum_{i-1}, sum_i)

算法伪代码:

  • 输入: A [ 1 , 2.... n ] 数组A[1,2....n]
  • 输出:连续子数组的最大和
maxSubArray(A)
	maxSum <- A[1];
	sum <- A[1];
	for i <- 2 to n
		if sum < 0 Then
			sum <- A[i];
		else
			sum <- sum + A[i];
		maxSum = Max(maxSum, sum);
	return maxSum; 

时间复杂度分析:

  • 输入规模: n n
  • 复杂度: O ( n ) O(n)

2、答:
定义: d p i i dp_i 为爬到第i阶台阶的方法数 ,则有

递推方程:

d p 1 = 1 d p 2 = 2 d p i = d p i 1 + d p i 2 dp_1 = 1 \quad dp_2 = 2\\ dp_i = dp_{i-1} + dp_{i-2}

算法伪代码:

  • 输入:台阶阶数 n n
  • 输出:爬到 n n 阶的方法数
climbStairs(n)
	if n == 1 Then return 1;
	if n == 2 Then return 2;
	dp_i_1 <- 2;
	dp_i_2 <- 1;
	for i <- 3 to n
		dp_i <- dp_i_1 + dp_i_2;
		dp_i_2 = dp_i_1;
		dp_i_1 = dp_i;
	return dp_i;
		 

时间复杂度分析:

  • 输入规模: log n \log{n}
  • 复杂度: O ( 2 log n ) O(2^{\log{n}})

3、答:
定义: d p [ i ] [ j ] S s i s i + 1 . . . s j dp[i][j]记录字符串S中s_is_{i+1}...s_j子串是否为回文的 ,则有

递推方程:

d p [ i ] [ i ] = T r u e d p [ i ] [ i + 1 ] = T r u e i f    s i = s i + 1 d p [ i ] [ j ] = T r u e i f    d p [ i + 1 ] [ j 1 ] = T r u e s i = s j dp[i][i] = True \\ dp[i][i + 1] = True \quad if \; s_i = s_{i+1} \\ dp[i][j] = True \quad if \; dp[i + 1][j - 1] = True 且 s_i = s_j

算法伪代码:

  • 输入:字符串 S S
  • 输出:最长回文子串 S S'
longestPalindrome(S)
	n <- S.length;
	dp <- new boolean[n][n]
	start <- 1;
	maxL <- 1;
	if n <= 1 Then return S;
	for i <-1 to n
		dp[i][i] <- True;
	for i <-1 to n - 1
		if S[i] = S[i + 1] Then 
			dp[i][i + 1] <- True;
			start <- i;
			maxL <- 2;
	for gap <- 2 to n - 1
		for i <- 1 to n - gap - i
			j <- i + gap;
			if dp[i + 1][j - 1] && S[i] = S[j] Then
				dp[i][j] <- True;
				start <- i;
				maxL <- gap + 1;
	return S.subString(start, start + gap);

时间复杂度分析:

  • 输入规模: n n
  • 复杂度: O ( n 2 ) O(n^2)

4、答:
定义: d p [ i ] [ j ] A i j dp[i][j] 记录到达网格A第i行第j列,最短路径 ,则有

递推方程:

d p [ i ] [ j ] = A [ i ] [ j ] i f    i = 1 j = 1 d p [ i ] [ j ] = d p [ i 1 ] [ j ] + A [ i ] [ j ] i f    j = 1 i > = 2 d p [ i ] [ j ] = d p [ i ] [ j 1 ] + A [ i ] [ j ] i f    i = 1 j > = 2 d p [ i ] [ j ] = M i n ( d p [ i 1 ] [ j ] , d p [ i ] [ j 1 ] ) + A [ i ] [ j ] dp[i][j] = A[i][j] \quad if \; i = 1 且 j = 1\\ dp[i][j] = dp[i - 1][j] + A[i][j] \quad if \; j = 1 且 i >=2\\ dp[i][j] = dp[i][j - 1] + A[i][j] \quad if \; i = 1 且 j >= 2\\ dp[i][j] = Min(dp[i - 1][j], dp[i][j - 1]) + A[i][j]

算法伪代码:

  • 输入:网格 A [ 1... m ] [ 1... n ] A[1...m][1...n]
  • 输出:到达网格第m行第n列的最短路径
findPath(A, m, n)
	dp <- new int[m][n];
	dp[1][1] <- A[1][1];
	path <- new Stack()
	for i <- 2 to m
		dp[i][1] <- dp[i - 1][1] + A[i][1];
	for j <- 2 to n
		dp[1][j] <- dp[1][j - 1] + A[1][j];
	for i <- 2 to m
		for j <- 2 to n
			dp[i][j] <- Min(dp[i - 1][j],dp[i][j - 1]) + A[i][j];
	i <- m; j <- n;
	while i >= 1 && j >= 1
		d <- dp[i][j] - A[i][j]
		if i > 1 && dp[i - 1][j] == d Then
			path.push(DOWN);
		else
			path.push(RIGHT);
	return path;

时间复杂度分析:

  • 输入规模: m n mn
  • 复杂度: O ( m n ) O(mn)

5、答:
定义: d p [ i ] [ j ] i j dp[i][j]为i时刻j位置可以收到得最多馅饼数

递推方程:
d p [ i ] [ j ] = P [ i ] [ j ] i f    i = 1 j = 4 , 5 , 6 d p [ i ] [ j ] = M a x ( d p [ i 1 ] [ j ] , d p [ i 1 ] [ j 1 ] , d p [ i 1 ] [ j + 1 ] ) + P [ i ] [ j ] dp[i][j] = P[i][j] \quad if \; i = 1 且 j = 4, 5, 6\\ dp[i][j] = Max(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + P[i][j]

算法伪代码:

  • 输入: P P [ i ] [ j ] i j 数组P,P[i][j]表示i时刻j位置落下得馅饼数
  • 输出:可以获得最多得馅饼数
getPie(P)
	t <- P.length;
	dp <- new int[13];
	dp[-1] <- 0; dp[11] <- 0; 
	dp[4] <- P[1][4];dp[5] <- P[1][5];dp[6] <- P[1][6];
	start <- 3;
	end <- 7;
	for i <- 2 to t
		start <- Max(--start, 0);
		end <- Min(++end, 10);
		for j <- start to end
			dp[j] <- Max(dp[j],dp[j - 1], dp[j + 1]) + P[i][j];
	return Max(dp);

时间复杂度分析:

  • 输入规模: 11 n 11n
  • 复杂度: O ( n ) O(n)
发布了11 篇原创文章 · 获赞 21 · 访问量 9240

猜你喜欢

转载自blog.csdn.net/BigPig_LittleTail/article/details/105194012