หมายเหตุทุก Subtask จำเป็นต้องรับ input ด้วย
Subtask 1 ()
เนื่องจากเราไม่สามารถลบส่วนใด ๆ ของเพลงได้เลย ฉะนั้นคำตอบจึงเป็น
Time Complexity:
Subtask 2 ()
เราสามารถ loop เพื่อหาตำแหน่งของเพลงที่ลบแล้วทำให้เกิดค่าความเหนื่อยน้อยที่สุดได้ ฉะนั้นคำตอบจึงเป็น
โดยกำหนดให้ สำหรับ อย่างไรก็ตาม คำตอบที่ถูกต้องอาจไม่จำเป็นต้องลบส่วนใด ของเพลงเลยก็ได้
Time Complexity:
Subtask 3 ()
เราสามารถลองทุกวิธีในการลบลำดับของเพลง โดยมีเงื่อนไขว่าต้องลบไม่เกิน ตำแหน่งเท่านั้น
Time Complexity:
Subtask 4 (ไม่มีเงื่อนไขเพิ่มเติม)
ปัญหานี้สามารถแก้ได้ด้วย Dynamic Programming โดยเราจะสมมุติ และ เป็นลำดับของเพลงที่ต้องเล่นก่อนและหลังดีด ใด ๆ ตามลำดับ โดยที่ สำหรับ
กำหนดให้ คือค่าความเหนื่อยที่น้อยที่สุดหลังจากเล่นลำดับของเพลงตั้งแต่ โดยที่ลบลำดับของเพลงไป ตำแหน่ง
Base Case:
Recurrence Formula:
คำตอบคือ
Time Complexity:
Solution Code:
#include <bits/stdc++.h> using namespace std; const int N = 305; int s[N]; long long p[N][N], dp[N][N]; int main() { int n, m, k; long long ans = 1e18; scanf(" %d %d %d", &n, &m, &k); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) scanf(" %lld", &p[i][j]); for (int i = 1; i <= m; i++) scanf(" %d", &s[i]); for (int i = 0; i <= m + 1; i++) for (int j = 0; j <= k; j++) dp[i][j] = 1e18; dp[0][0] = 0; for (int i = 0; i <= m; i++) for (int j = 0; j <= k; j++) for (int l = 0; j + l <= k && i + l + 1 <= m + 1; l++) dp[i + l + 1][j + l] = min(dp[i + l + 1][j + l], dp[i][j] + p[s[i]][s[i + l + 1]]); for (int i = 0; i <= k; i++) ans = min(ans, dp[m + 1][i]); printf("%lld\n", ans); return 0; }