算法第三章做業
若是一個問題能夠用動態規劃算法解決,則老是能夠在多項式時間內解決的。ios
T F算法
1-2數組
最優二叉搜索樹的根結點必定存放的是搜索機率最高的那個關鍵字。spa
F設計
1-3遞歸
用動態規劃而非遞歸的方法去解決問題時,關鍵是將子問題的計算結果保存起來,使得每一個不一樣的子問題只須要被計算一次。子問題的解能夠被保存在數組或哈希散列表中。ci
T io
D、在動態規劃中,咱們要推導出一個子問題的解與其餘子問題解的遞推關係。要將這種關係轉換爲自底向上的動態規劃算法,咱們須要以正確的順序填寫子問題解的表格,使得在解任一子問題時,全部它須要的子問題都已經被解決了。在下列關係式中,哪個是不可能被計算的? (2分)class
A(i,j)=min(A(i−1,j),A(i,j−1),A(i−1,j−1))stream
A(i,j)=F(A(min{i,j}−1,min{i,j}−1),A(max{i,j}−1,max{i,j}−1))
A(i,j)=F(A(i,j−1),A(i−1,j−1),A(i−1,j+1))
A(i,j)=F(A(i−2,j−2),A(i+2,j+2))
2-2
C、給定遞推方程 f
i,j,k
=f
i,j+1,k
+min
0≤l≤k
{f
i−1,j,l
+w
j,l
}。
D、要經過循環解此方程,咱們必定不能用下列哪一種方法填表? (2分)
for k in 0 to n: for i in 0 to n: for j in n to 0
for i in 0 to n: for j in 0 to n: for k in 0 to n
for i in 0 to n: for j in n to 0: for k in n to 0
for i in 0 to n: for j in n to 0: for k in 0 to n
2-3
切原木問題:給定一根長度爲N米的原木;另有一個分段價格表,給出長度L=1,2,⋯,M對應的價格P
L
。要求你找出適當切割原木分段出售所能得到的最大收益R
N
。例如,根據下面給出的價格表,若要出售一段8米長的原木,最優解是將其切割爲2米和6米的兩段,這樣能夠得到最大收益R
8
=P
2
+P
6
=5+17=22。而若要出售一段3米長的原木,最優解是根本不要切割,直接售出。
Length L 1 2 3 4 5 6 7 8 9 10
Price P
L
1 5 8 9 10 17 17 20 23 28
下列哪句陳述是錯的?(3分)
此問題能夠用動態規劃求解
若N≤M,則有R
N
=max{P
N
,max
1≤i<N
{R
i
+R
N−i
}}
若N>M,則有R
N
=max
1≤i<N
{Ri+RN−M }算法的時間複雜度是O(N2 )
單調遞增最長子序列
設計一個O(n2)時間的算法,找出由n個數組成的序列的最長單調遞增子序列。
#include <iostream>
using namespace std;
int dl(int a[], int b[],int n) {
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++)
{
if (a[j] < a[i]&& b[j]>b[i] - 1) {
b[i] = b[j] + 1;
}
}
}
int t = b[1];
for (int k = 0; k < n; k++)
{
if (b[k] > t) {
t = b[k];
}
}
return t;
}
int main() {
int n;
cin >> n;
int *a = new int[n];
int *b = new int[n]();//置爲0;
for (int i = 0; i < n; i++) {
b[i]++;
}
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
cout << dl(a, b, n);
system("pause");
}
租用遊艇問題 (17 分)
題目來源:王曉東,《算法設計與分析》
長江遊艇俱樂部在長江上設置了n個遊艇出租站1,2,…,n。遊客可在這些遊艇出租站租用遊艇,並在下游的任何一個遊艇出租站歸還遊艇。遊艇出租站i到遊艇出租站j之間的租金爲r(i,j),1<=i<j<=n。試設計一個算法,計算出從遊艇出租站1 到遊艇出租站n所需的最少租金。
#include <iostream>
int dp[100][100];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
scanf("%d",&dp[i][j]);
}
}
for(int k=2;k<n;k++)
{
for(int i=1;i<=n-k;i++)
{
int j=i+k;
for(int z=i+1;z<=j;z++)
{
int temp=dp[i][z]+dp[z][j];
if(dp[i][j]>temp)
dp[i][j]=temp;
}
}
}
printf("%d\n",dp[1][n]);
return 0;
}