Алqoritm Floyd-Warshall-ı a_{ij} matrisində işə salırıq ki, hər bir hərfi istənilən digər hərfə dəyişmək üçün ən qısa müddəti təyin etsin.
Matrisin xərclərini matrisini yaradacağıq ki, cst[i][j]~(1 \le i \le n) s[i - 1] hərfini hərfinə dəyişməyin ən az gün sayını saxlasın.
Daha sonrakı hesablama üçün dünyanın hissə cəmləri olan matris quraraq xərclər matrisinin xərclərini içərən xüsusiyyət təqdim edirik:
dp[i][j] sətirinin ilk hərflərini Bessinin yeni tələblərinə uyğun olmayan bir sətirə çevirmək üçün ən son hərfini son sətirdə hərfi ilə əvəzləməklə saxlamaq üçün ən az gün sayını saxlayırıq.
Dinamika tənliklərini yazıq:
sətirinin ilk i - 1 hərfi artıq hərfi ilə sonlanan bir sətirə çevrilmişdir. O zaman biz sadəcə s[i - 1] hərfini ilə əvəz edirik ki, bu cst[i][j] gün davam edəcək.
Yeni sətirdə son hərfi olmalıdır, buna görə də dp[i - k][0], dp[i - k][1], ..., dp[i - k][m - 1] dəyərlərini nəzərdən keçiririk. Onlar arasında ən kiçiyini seçirik. Yəni, sətirinin ilk i - k hərfini Bessinin yeni tələblərinə uyğun bir sətirə çevirmək və son hərfi s[i - k], s[i - k + 1], ..., s[i - 1] dəyişikliyinə sonra ilə edilir, bu xərcə baxır:
Bu yığıncağı sabit müddətmişdə hesablamaq üçün prefiks dizi kullanışının:
adlı əlavə bir dizini saxlamaq istəyirik ki,
Bu vəziyyətin dinamikası üçün tənlik (i \ge k) belə olacaq:
Sonra iki variantdan dp[i][j] üçün ən kiçik olanı seçəcəyik.
Mesələ cavabı
Yeni Bessi sözünün hansı hərfləri ilə tamamlanacağı bizim üçün əhəmiyyətli deyil.
Misal
Bu misalda ən yaxşı həlledici hərfi hərfdə uyğun ilə dəyişmək, sonra ilə və sonra c ilə dəyişməkdir. İxtisarların ümumi xərci 1 + 4 + 0 + 0 = 5 gün olacaqdır ki, nəticə sətiri görünüşündə olacaqdır.
a_{ij} matrisi üzrə xərclər matris quracağıq. matrisini də hesablayacağıq.
Bütün dp[1][j]~(0 \le j \le 4) dəyərləri olacaqdır, çünki zolağın uzunluğu k = 2-dən az ola bilməz. Nəticə olaraq, mn[1] = +∞.
Bir şey dp[2][j] (0 ≤ j ≤ 4) dəyərlərini hesablamaq üçün baxlanacaq:
dp[2][0] = ("ab" \to "aa") = cnt[''''] + cnt[''][''] = 0 + 2 = 2;
dp[2][1] = ("ab" \to "bb") = cnt[''''] + cnt[''][]['b'] = 1 + 0 = 1;
dp[2][2] = ("ab" \to "cc") = cnt['']['c'][][''][]['c'] = 4 + 4 = 8;
dp[2][3] = ("ab" \to "dd") = cnt[''][]['d'][][''][]['d'''] = 4 + 4 = 8dp[2][4] = ("ab" "ee") = cnt['a'][][''][]['b'][][''] = 4 + 4 = 8; \end{itemize} mn[2] = min(dp[2][0], dp[2][1], dp[2][2], dp[2][3] , dp[2][4]) = 1 Qiyməti dp[3][j] (0 j 4) tənliyi dp[3][j] = ps[3][j] - ps[1][j] + mn[1] mn[1] = +∞ olduğu üçün istifadə ediləcək. k=2 olduğu üçün 3-də zarifliklər üşündə qurulmuş zarifliklər təsir edəcək: \begin{itemize} \item dp[3][0] = dp[2][0] + cst['c'][][''] = 2 + 5 = 7 ("aaa")dp[3][1] = dp[2][1] + cst['c'][]['[] = 1 + 5 = 6 ("bbb")dp[3][2] = dp[2][2] + cst['c']['][''][]['[]'] = 8 + 0 = 8~("ccc");
dp[3][3] = dp[2][3] + cst[''][]['d'][]["] = 8 + 3 = 11 ("ddd")dp[3][4] = dp[2][4] + cst['c'][]'][''][]']['] = 8 + 2 = 10 ("eee"); \end{itemize} Qiyməti dp[4][0] iki yolla əldə etmək mümkündür: \begin{itemize} \item dp[4][0] = dp[3][0] + cst['d'][]'][''][][''] = 7 + 5 = 12~("aaaa");
və ya
dp[4][0] = ps[4][0] - ps[2][0] + mn[2] = 12 - 2 + 1 = 11~("bbaa");
İkinci xərc daha yaxşıdır, zolağın sonuna iki bərabər '' hərfi əlavə olunur. mn[2] = 1 dəyəri "" zərfi nəticəsində əldə edilir, yəni optimal xətir formalı dəqiq qurtaracaq "".
Alqoritm Tətbiqi
Aşağıdakı dizinləri elan edirik:
— hərfi -ni -lə əvəz etməyin minimum xərcidir.
cst[i][j] — orijinal sətirinin i-ci hərfini (1-dən indeksasiyaçı) hərfinə əvəz etməyin xərcidir. Formal olaraq
hərfi dəyişməni asanlıqla tapmaq üçün dizi uzunluğunu içərir:
dp[i][j] — sətirinin ilk hərfini ilə uyğun bir sətirə çevirmək üçün minimum gün sayını saxlayan, sonların -hərfləri -də olmalıdır (zolaq qrupları olduğundan tələblər).
— bütün dp[i][j]-dən olan bütün -lərdə minimum: ilk sənətləri üçün ən yaxşı həll.
#define MAXN 100005
#define ALPH 26
int a[ALPH][ALPH], cst[MAXN][ALPH], ps[MAXN][ALPH], dp[MAXN][ALPH], mn[MAXN];Məlumatları oxuyuruq.
cin >> n >> m >> k;
cin >> s;
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
cin >> a[i][j];Floyd-Warshall alqoritmini matrisi -da işə salırıq. Bitdikdən sonra, hərfi -dən hərfi -ə dəyişdirmək üçün ən kiçik gün sayını saxlayır.
for (x = 0; x < m; x++)
for (i = 0; i < m; i++)
for (j = 0; j < m; j++)
a[i][j] = min(a[i][j], a[i][x] + a[x][j]);Bizdə m \le 26 hərf var. Xərclər matris quracağıq belə ki, cst[i][j]~(1 \le i \le n) n[i - 1] hərfini hərfinə dəyişmək üçün ən kiçik gün sayını saxlasın. Bütün sətirindəki hərf sayı -dan başlayır.
Daha sonrakı hesablama üçün dünyanın sərhəd cəmləri olan matrisini SAXLAYACAQ:
for (i = 1; i <= n; i++)
for (j = 0; j < m; j++)
{
cst[i][j] = a[s[i - 1] - 'a'][j];
ps[i][j] = ps[i - 1][j] + cst[i][j];
}Dizaynları initializasiya edirik.
memset(dp, 0x3f, sizeof dp);
memset(mn, 0x3f, sizeof mn);
mn[0] = 0;massivi massivlərin dəyərini hesablamaq üçün:
for (i = 1; i <= n; i++)
for (j = 0; j < m; j++)
{Hazırkı xətir qutuların ən ucuzunu təyin edin. Orijinal s[i - 1] sətirinin -ci hərfini ilə əvəz edirik. Yəni:
Mövcud i - 1 harf ilə sonlanan zarflar artıq dəyişdirilib;
hərfidir -cü son zərf hərfini ;
xərci dp[i - 1][j] + cst[i][j] əvəzinə olan qiymətdir.
Köhnə xərc zərfini -lü yeni zərfə başlayır, bu yeni zərfə ilə şəklindəyə uzunluğu olur. Bunun üçün: