Subtask 1 ( )
เราสามารถลองทุกวิธีในการเลือกแบตเตอรี่ ก้อนและดูว่าในแต่ละกรณีที่ทำให้ม้าไปถึงจุดสิ้นสุด ใช้เวลาชาร์จเท่าไร และเก็บกรณีที่ ใช้เวลาชาร์จน้อยที่สุด
Time Complexity:
Subtask 2 ( N ≤ 1000, X ≤ 500, Y = 0 )
ใน subtask นี้ เราไม่จำเป็นต้องคำนึงถึงค่า เนื่องจากจุดเริ่มต้นเรามีค่า
สังเกตว่าปัญหานี้คล้ายกับปัญหา Knapsack แต่แทนที่เราจะทำให้ผลรวม ไม่เกิน และผลรวม มากที่สุด เราต้องทำให้ผลรวม
เกิน และผลรวม น้อยที่สุด คำนึงด้วยว่าหากม้าไปเกิน X สามารถเก็บค่าไว้ที่ช่อง X ได้เลย เพราะถือว่าถึงจุดหมายเหมือนกัน
https://en.wikipedia.org/wiki/Knapsack_problem
Time Complexity:
Subtask 3 ( ไม่มีเงื่อนไขเพิ่มเติม )
สังเกตว่าเราต้องพิจารณาทั้งสองแกนในการคำนึงว่าเราถึงจุดหมายแล้วหรือไม่ เราจึงต้องเพิ่มมิติในการเก็บค่าของตาราง knapsack จาก ตารางขนาด เป็นขนาด
เนื่องจากตารางขนาด มีขนาดเกิน Memory Limit เราสามารถลดการใช้ Memory ด้วยการเก็บแค่ค่า ปัจจุบันและ ค่า ก่อนหน้าทำให้ขนาดตารางเหลือ
Time Complexity:
Solution Code:
#include <bits/stdc++.h> using namespace std; #define MAXL 1000000000000000000ll int n, x, y; array<int, 3> arr[1010]; long long dp[2][550][550]; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> x >> y; for (int i = 0; i < n; i++) { cin >> arr[i][0] >> arr[i][1] >> arr[i][2]; } for (int i = 0; i <= x; i++) { for (int j = 0; j <= y; j++) { dp[0][i][j] = MAXL; } } dp[0][0][0] = 0; for (int i = 0; i < n; i++) { for (int j = 0; j <= x; j++) { for (int k = 0; k <= y; k++) { dp[(i + 1) % 2][j][k] = dp[i % 2][j][k]; } } for (int j = 0; j <= x; j++) { for (int k = 0; k <= y; k++) { dp[(i + 1) % 2][min(j + arr[i][0], x)][min(k + arr[i][1], y)] = min(dp[(i + 1) % 2][min(j + arr[i][0], x)][min(k + arr[i][1], y)], dp[i % 2][j][k] + arr[i][2]); } } } long long ans = dp[n % 2][x][y]; cout << ((ans == MAXL) ? -1 : ans) << '\n'; return 0; }