作業系列 演算法第3章上機實踐報告

2022-08-17 18:45:10 字數 1856 閱讀 5804

1.實踐題目

7-3編輯距離問題

2.問題描述

設a和b是2個字串。要用最少的字元操作將字串a轉換為字串b。這裡所說的字元操作包括 (1)刪除乙個字元; (2)插入乙個字元; (3)將乙個字元改為另乙個字元。 將字串a變換為字串b所用的最少字元運算元稱為字串a到 b的編輯距離,記為d(a,b)。 對於給定的字串a和字串b,計算其編輯距離 d(a,b)。

第一行是字串a,檔案的第二行是字串b。

輸出編輯距離d(a,b)

在這裡給出一組輸入。例如:

fxpimu

xwrs

在這裡給出相應的輸出。例如:

5

3.演算法描述

設a串長度為l1,b串長度為l2,那麼開乙個dp[i][j]記錄當長度為i的a串的時候變成長度為j的b串時的最短編輯距離。那麼dp[0...l1][0]初始化為0...l1,dp[0][0...l2]初始化為0...l2.

那麼dp[i][j]的狀態轉移方程就是

dp[i][j]=min(min(dp[i][j-1]+1,dp[i-1][j]+1),dp[i-1][j-1]+(a[i-1]!=b[j-1]));

//也就是由dp[i][j-1]+1和dp[i-1][j]+1和dp[i-1][j-1]+(a[i-1]!=b[j-1])的最小值轉移過來的;

當時做的時候沒想太多,交了一發有bug的**但是過了,應該是樣例沒特意卡空串。

#include#include#includeusing namespace std;

const int maxn = 2005;

char a[maxn];

char b[maxn];

int dp[maxn][maxn];

int main()

}  }

cout《很明顯上面的**是有bug的,因為我用cin輸入根本就不需要特判l1還有l2是否為0,不過當時沒有在意這個細節,現附上改進**

#include#includeusing namespace std;

const int maxn = 2005;

char a[maxn],b[maxn];

int dp[maxn][maxn];

int main()

{ cin.getline(a,2001);

cin.getline(b,2001);

int l1 = strlen(a);

int l2 = strlen(b);

for(int i = 1;i<=l1;i++)

dp[i][0]=i;

for(int j =1;j<=l2;j++)

dp[0][j]=j;

for(int i = 1;i<=l1;i++)

for(int j = 1;j<=l2;j++)

dp[i][j]=min(min(dp[i][j-1]+1,dp[i-1][j]+1),dp[i-1][j-1]+(a[i-1]!=b[j-1]));

cout<4.演算法時間和空間複雜度

兩層for迴圈,時間複雜度是o(l1*l2);

二維dp陣列,空間複雜度是o(l1*l2);

5.心得體會

對dp還是不夠熟悉,第三題用了十來二十分鐘才弄出dp方程式,如果是權哥估計看到題目沒過多久就能弄出來了

由於隊內分工的時候dp是權哥搞的,所以我對dp的熟悉度不算太高,導致做題的時候用的時間比我想象中要多,感覺還是要多做一點dp的題目保持對dp的題感。(雖然正式比賽的時候dp也是權哥搞的,我最多也就和他討論一下思路)

演算法第5章上機實踐報告

7 2 工作分配問題 20 分 設有n件工作分配給n個人。將工作i分配給第j個人所需的費用為cij 設計乙個演算法,對於給定的工作費用,為每乙個人都分配1 件不同的工作,並使總費用達到最小。輸入資料的第一行有1 個正整數n 1 n 20 接下來的n行,每行n個數,表示工作費用。將計算出的最小總費用輸...

演算法第5章上機實踐

1.實踐題目 工作分配問題 2.問題描述 7 2 工作分配問題 20 分 設有n件工作分配給n個人。將工作i分配給第j個人所需的費用為cij 設計乙個演算法,對於給定的工作費用,為每乙個人都分配1 件不同的工作,並使總費用達到最小。輸入資料的第一行有1 個正整數n 1 n 20 接下來的n行,每行n...

演算法第4章實踐報告

實踐題目 程式儲存問題 問題描述 設有n 個程式要存放在長度為l的磁帶上。程式i存放在磁帶上的長度是 li,1 i n。程式儲存問題要求確定這n 個程式在磁帶上的乙個儲存方案,使得能夠在磁帶上儲存盡可能多的程式。對於給定的n個程式存放在磁帶上的長度,計算磁帶上最多可以儲存的程式數。第一行是2 個正整...