สมมติว่าเรามีสตริง s เราต้องทำให้สตริงนี้เป็นพาลินโดรม ในแต่ละขั้นตอนเราสามารถแทรกอักขระใดก็ได้ในตำแหน่งใด ๆ เราต้องหาจำนวนอักขระขั้นต่ำที่ต้องใช้เพื่อสร้าง palindrome นี้ หากสตริงเป็นเหมือน "บ้า" คำตอบจะเป็น 2 เนื่องจากเราสามารถเติม "da" ก่อน "mad" หรือ "am" หลัง "mad" เพื่อสร้าง palindrome นี้ได้
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
- กำหนดฟังก์ชัน lcs() ซึ่งจะใช้เวลา s, x :=s
- n :=ขนาดของ s
- ย้อนกลับสตริง x
- s :=เชื่อมช่องว่างก่อน s, x :=ต่อช่องว่างก่อน x
- กำหนดขนาดอาร์เรย์ 2 มิติหนึ่ง dp (n + 1) x (n + 1)
- สำหรับการเริ่มต้น i :=1 เมื่อฉัน <=n อัปเดต (เพิ่ม i ขึ้น 1) ทำ −
- สำหรับการเริ่มต้น j :=1 เมื่อ j <=n อัปเดต (เพิ่ม j โดย 1) ทำ −
- dp[i, j] :=สูงสุดของ dp[i – 1, j] และ dp[i, j - 1]
- ถ้า s[i] เหมือนกับ x[j] แล้ว −
- dp[i, j] :=สูงสุดของ dp[i, j] และ dp[i – 1, j - 1] + 1
- สำหรับการเริ่มต้น j :=1 เมื่อ j <=n อัปเดต (เพิ่ม j โดย 1) ทำ −
- ส่งคืน dp[n, n]
- จากวิธีการหลักขนาดส่งคืนของ s – lcs(s)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h> using namespace std; class Solution { public: int lcs(string s){ string x = s; int n = s.size(); reverse(x.begin(), x.end()); s = " " + s; x = " " + x; vector < vector <int> > dp(n + 1, vector <int>(n + 1)); for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); if(s[i] == x[j]){ dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1); } } } return dp[n][n]; } int minInsertions(string s) { return s.size() - lcs(s); } }; main(){ Solution ob; cout << (ob.minInsertions("mad")); }
อินพุต
“mad”
ผลลัพธ์
2