演算法競賽入門經典 例題9 8

2021-10-03 22:06:41 字數 2618 閱讀 8667

uva 01625

color length

某個城市因為修路,需要將上下兩車道關閉為上下單車道,即每個方向需要將兩車道的車流合併到一條車道中。每輛車的顏色用大寫字母表示,要求合併後的車流中每種顏色車的最大距離之和最小,例如合併後的車流為gbybryrgb,則距離分別為l(g) = 7l(b) = 7l(y) = 3l(r) = 2,和為19

每一步要做的決策就是從第1條車道,或者第2條車道中選擇一輛車匯入到新的車流中。假設已經從第1條車道匯入了i輛車且從第2條車道匯入了j輛車,現在需要判斷是選取第i輛車還是第j輛車,然後計算新的最小值。如果新的車是該顏色的最後一輛車,那麼要往前去找該顏色的第1輛車,也就是要把最多26種顏色的車的首位置都記錄下來,這樣狀態空間會有28維,顯然這種方法是無後效的,但更顯然的是這個方法不可行。

上面的問題在於只根據這輛車的顏色計算了該顏色的l值,而沒有考慮到對其它顏色l值的影響。如果可以考慮所有顏色的l值,也就是考慮了所有l值的和:

這種方法不需要知道前面i + j輛車中每種顏色的車的起始位置,只需要知道每種顏色是否結束就可以了,而顏色是否結束只和(i, j)有關係,保證了最優子結構和無後效性。

這樣問題就變成了計算left(i, j),表示在從兩條車道分別選取i輛車和j輛車時,在0 ~ i0 ~ j中至少出現過一次且在i + 1 ~ nj + 1 ~ m中還會出現的顏色的數量。在二重迴圈內對顏色進行列舉,根據每種顏色的起始位置和結束位置即可計算left。這裡0表示的是0輛車,如果0表示的是下標,則left(0, 0)就直接表示了兩輛車的情況,沒有車和只有一輛車的情況需要單獨寫,感覺更麻煩一些。

有了left,就可以計算最小值了,遞推公式為length[i][j] = min(length[i - 1][j] + left[i - 1][j], length[i][j - 1] + left[i][j - 1])。如果新的顏色是第2個至最後乙個,則新的顏色也需要遞增,left[i - 1][j]也包括新的顏色;如果新的顏色是第1個(或者同時也是最後1個),則不需要遞增新的顏色,left[i - 1][j]不包括新的顏色。

但是這樣寫起來有問題,因為0表示選擇了0輛車,再減1就變成了負數了,因此**寫成了向上遞推的形式。

#include

#include

#include

#include

#define a_2_o(c) ((c) - 'a')

using

namespace std;

void

calposition

(const string &str1,

const string &str2, vector>

&fstpos, vector>

&lstpos)

while

(i < str1.

size()

)while

(j < str2.

size()

)while

(i >

0&& j >0)

while

(i >0)

while

(j >0)

}void

findminimumcolorlength

(const string &str1,

const string &str2)}}

} length[0]

[0]=

0;for(size_t i =

0; i <= str1.

size()

; i++)if

(length[i]

[j +1]

> length[i]

[j]+ left[i]

[j])}}

cout << length[str1.

size()

][str2.

size()

]<< endl;

}int

main()

return0;

}/*2aaabbcy

abbbcdeey

gbby

yrrgb

*/

演算法競賽入門經典例題

7744問題 問題 輸出所有形如aabb的四位完全平方數 即前兩位數字相等,後兩位數字也相等 include include int main 開燈問題 include include define maxn 1010 int a maxn int main int n,k,first 1 mems...

演算法競賽入門經典 例題4 1

uva1339 ancient cipher 題目意思為判斷明文是否可以經過位置變換以及字母替換得到密文。因為不需要輸出替換方案,只判斷存在性,那就先不考慮搜尋。位置變換不用考慮,因為只要長度一樣,就肯定能逆回去,關鍵是字母替代。可以把明文和密文先進行排序,然後看模式是否相同,比如題目中第一組測試資...

演算法競賽入門經典 例題4 5

uva512 spreadsheet tracking 給定乙個 和一些操作序列,輸出給定單元格在這些操作後的位置。如果在整個 上模擬操作,那麼就需要記錄原始 和最終 中每乙個單元格的對應關係,比如可以通過給單元格內容編號,新加入的單元格編號全0,刪除原始單元格則編號全部改 1,最後在整個 中搜尋原...