HIT研究生算法作業4

1、答:
定義:maxSumiA[1,...i];sumimaxSum_i爲A[1,...i]連續子數組的最大和;sum_i爲當前連續子數組的和,則有

遞推方程:

sumi=A[i]if  i=1    sumi1<0sumi=sumi1+A[i]if  sumi1>=0maxSumi=A[i]if  i=1maxSumi=Max(maxSumi1,sumi)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; 

時間複雜度分析:

  • 輸入規模:nn
  • 複雜度:O(n)O(n)

2、答:
定義:dpiidp_i 爲爬到第i階臺階的方法數,則有

遞推方程:

dp1=1dp2=2dpi=dpi1+dpi2dp_1 = 1 \quad dp_2 = 2\\ dp_i = dp_{i-1} + dp_{i-2}

算法僞代碼:

  • 輸入:臺階階數nn
  • 輸出:爬到nn階的方法數
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;
		 

時間複雜度分析:

  • 輸入規模:logn\log{n}
  • 複雜度:O(2logn)O(2^{\log{n}})

3、答:
定義:dp[i][j]Ssisi+1...sjdp[i][j]記錄字符串S中s_is_{i+1}...s_j子串是否爲迴文的,則有

遞推方程:

dp[i][i]=Truedp[i][i+1]=Trueif  si=si+1dp[i][j]=Trueif  dp[i+1][j1]=Truesi=sjdp[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

算法僞代碼:

  • 輸入:字符串SS
  • 輸出:最長迴文子串SS'
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);

時間複雜度分析:

  • 輸入規模:nn
  • 複雜度:O(n2)O(n^2)

4、答:
定義:dp[i][j]Aijdp[i][j] 記錄到達網格A第i行第j列,最短路徑,則有

遞推方程:

dp[i][j]=A[i][j]if  i=1j=1dp[i][j]=dp[i1][j]+A[i][j]if  j=1i>=2dp[i][j]=dp[i][j1]+A[i][j]if  i=1j>=2dp[i][j]=Min(dp[i1][j],dp[i][j1])+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;

時間複雜度分析:

  • 輸入規模:mnmn
  • 複雜度:O(mn)O(mn)

5、答:
定義:dp[i][j]ijdp[i][j]爲i時刻j位置可以收到得最多餡餅數

遞推方程:
dp[i][j]=P[i][j]if  i=1j=4,5,6dp[i][j]=Max(dp[i1][j],dp[i1][j1],dp[i1][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]

算法僞代碼:

  • 輸入:PP[i][j]ij數組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);

時間複雜度分析:

  • 輸入規模:11n11n
  • 複雜度:O(n)O(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章