Moortal Kombat#10292

Moortal Kombat (Həll təhlili)

Ал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:

ps[i][j] = cst[i][1] + cst[i][2] + ... + cst[i][j]

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:

cst[i - k + 1][j] + cst[i - k + 2][j] + ... + cst[i][j]

Bu yığıncağı sabit müddətmişdə hesablamaq üçün prefiks dizi kullanışının:

cst[i - k + 1][j] + cst[i - k + 2][j] + ... + cst[i][j] = ps[i][j] - ps[i - k][j]

adlı əlavə bir dizini saxlamaq istəyirik ki,

mn[i] = min(dp[i][0], dp[i][1], ..., dp[i][m - 1])

Bu vəziyyətin dinamikası üçün tənlik (i \ge k) belə olacaq:

dp[i][j] = ps[i][j] - ps[i - k][j] + mn[i - k]

Sonra iki variantdan dp[i][j] üçün ən kiçik olanı seçəcəyik.

Mesələ cavabı

mn[n] = min(dp[n][0], dp[n][1], ..., dp[n][m - 1])

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:

və ya

İ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:

#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:

ps[i][j] = cst[i][1] + cst[i][2] + ... + cst[i][j]
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:

dp[i][j] = min(dp[i][j], dp[i - 1][j] + cst[i][j]);

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: