算法设计例题
【动态规划专题】
例 1
正解:
(1)17条
(2)从A到B最短路径的长度是7,从A沿着右下方向取寻找路径,第一次找出距离A一步的点上的条数,第二次找出距离A两步的点上的条数,重复七次,假设 D[i][j] 是对应点上的条数,那么有 D[i][j] = D[i-1][j] + D[i][j-1] 。
(3)
例 2
正解:
input: A[1...n]
output: (p,q)
The pseudocode is as follows
operate()
{
mid = (1+n)/2
S[mid-1] = A[mid-1]
T[mid+1] = A[mid+1]
for(i = mid-2; i>=1 ;i--)
S[i] = S[i+1] + A[i]
for(i = mid+2; i<=n ;i++)
T[i] = T[i-1] + A[i]
max(S,p)
max(T,q)
return (p,q)
}
例 3
正解:
此问题的核心就是背包问题
(1)
if(j<ti)
X[i,j] = X[i-1,j]
else if(i>0&&j>ti)
X[i,j] = max{X[i-1,j],X[i-1,j-ti]+xi}
(2)
for i=0 to n
X[i,0] = 0
for j=0 to n
X[0,j] = 0 //initialization
for i=1 to C
for j=1 to n
X[i,j] = X[i-1,j]
if(j>=ti) X[i,j] = max{X[i,j],X[i-1,j-ti]+xi}
end for
end for //operation
(3)
算法复杂度为表的大小O(nC)
【随机算法专题】
(1)
Input : Point set P ,Reference point r
Output: Hypervolume hv
sort(P) // sort by the x-coordinate
hv = 0, y = r.y
for i=1 to |P|
hv += (y-P[i].y)*(r.x-P[i].x)
y = P[i].y
end for
Complexity: O(NlogN)
(2)
Input : Point set P ,Reference point r
Output: Hypervolume hv
x = min(P.x)
y = min(P.y)
sum = 0
for i=1 to N
r1 = rand()
r2 = rand()
rx = (r.x-x)*r1 + x
ry = (r.y-y)*r2 + y // coordinates of the random points
for j=1 to |P|
if P[j].x<=rx && P[j].y<=ry
sum++
break
end if // if it's within the range
end for
end for // generate N points
return (sum/N)*(r.x-x)*(r.y-y) // the correct hv
Complexity: O(N)
.
.
【分治专题】
.
.
正解:
(1)
首先计算 t1 = min{n,k},t2 = min{2n,k},只考虑A[1…t1] 和 B[1…t2]中第k小元素。
用分治的方法,设计递归子程序 Searchkth(A[] , low1 , high1 , B[] , low2 , high2 , k),用于求出A[low1…high1] 和 B[low2…high2] 中第k小元素,考虑 A[ |(low1+high1)/2| ] 和 B[ |(low2+high2)/2| ],
当 A[mid1] < B[mid2] 时 ,
情况一:mid1-low+1+mid2-low2+1>=k, 则B[ |(low2+high2)/2| ] 之后的元素不可能是第k小元素;
情况二:mid1-low+1+mid2-low2+1<k, 则A[ |(low1+high1)/2| ] 之前的元素不可能是第k小元素;
A[mid1]>=B[mid2]的情况可以类似推出,这是一种“简而治之”的算法设计思想
(2)
Input : A[1...n] , B[1...2n] , k (increasing order)
Output: the kth little element
Findkthelement()
{
t1 = min{n,k}
t2 = min{2n,k} // 预处理一下可以减少处理量,不进行这步也无妨
x = Searchkth(A[],1,t1,B[],1,t2,k)
output x
}
Searchkth(A[],low1,high1,B[],low2,high2,k)
{
if(low1>high1)
if(low2+k-1>high2) return ERROR
else return B[low2+k-1]
end if
if(low2>high2)
if(low1+k-1>high1) return ERROR
else return A[low1+k-1]
end if // 接口处
mid1 = |_(low1+high1)/2_|
mid2 = |_(low2+high2)/2_|
if(A[mid1]<B[mid2])
if(mid1-low1+1+mid2-low2+1>=k)
return Searchkth(A[],low1,high1,B[],low2,mid2,k)
else return Searchkth(A[],mid1+1,high1,B[],low2,high2,k-(mid1-low1+1))
end if
else
if(mid1-low1+1+mid2-low2+1>=k)
return Searchkth(A[],low1,mid1,B[],low2,high2,k)
else return Searchkth(A[],low1,high1,B[],mid2+1,high2,k-(mid2-low2+1))
end if
end if
}
complexity: O(logn)
(3)
一种向下挖掘深度的算法,复杂度是O(logn)