มี ร้าน( เป็นเลขคู่) โดยร้านที่ มีราคา
โดยต้องแบ่งช่วงการกินข้าวเป็นช่วงๆ สมมติว่ามี ช่วง โดยต้องให้ และ คือจำนวนร้านที่กินในช่วงการกินข้างที่ และ ต้องเป็นเลขคู่
โดยช่วงการกินที่ จะเริ่มกินจากร้านที่ ไปจนถึงร้านที่
ช่วงการกินที่ จะเริ่มกินจากร้านที่ ไปจนถึงร้านที่
ช่วงการกินที่ จะเริ่มกินจากร้านที่ ไปจนถึงร้านที่
สมมติให้ช่วงการกินที่ กินจากร้านที่ ไปร้านที่ โดยช่วงการกินจะแบ่งเป็น รอบ รอบแรกจะกินร้านที่ จนถึงร้านที่ และกินเฉพาะร้านที่มีราคาเป็นเลขคี่ รอบที่สองจะกินจากร้านที่ จนถึงร้านที่ และกินเฉพาะร้านที่มีราคาเป็นเลขคู่
ให้ผลรวมราคาที่กินไปของรอบแรกของช่วงที่ เป็น และให้ผลรวมราคาของรอบที่สองที่กินไปของช่วงที่ เป็น เราต้องให้ และ
ให้หาว่า มีค่าน้อยสุดคือเท่าไหร่
สังเกตได้ว่าการที่ แปลว่า สำหรับทุกๆ
จะได้ว่าถ้าให้ ค่า ที่น้อยที่สุดโดยที่คิดแค่ ร้านแรก และช่วงการกินช่วงสุดท้ายจบที่ร้านที่ สังเกตได้ว่า
ถ้าเราให้ ผลรวมของทุกๆ ราคาเมื่อราคาเป็นเลขคี่เมื่อคิดแค่ ร้านแรก และ ผลรวมของทุกๆ ราคาเมื่อราคาเป็นเลขคู่เมื่อคิดแค่ ร้านแรก
เราจะให้
เราจะพิจารณาผลรวมราคาที่กินไปของรอบแรกก่อน นั่นก็คือ
จากนั้นเราจะพิจารณาผลรวมราคาที่กินไปของรอบที่สอง นั่นก็คือ
ซึ่งทั้งคู่สามารถเช็คได้ใน เนื่องจากเราต้องเช็คทุกๆ ที่ สำหรับ ซึ่งต้องเช็ค จุด แล้วเราต้องทำ สำหรับทุกๆ จะได้ว่าเวลารวมที่จำเป็นต้องใช้คือ
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int inf = 1e9;
int main(){
cin.tie(NULL)->sync_with_stdio(false);
int n, v, w; cin >> n >> v >> w;
vector<int> a(n + 1), p_odd(n + 1), p_even(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
p_odd[i] = p_odd[i - 1];
p_even[i] = p_even[i - 1];
if (a[i] % 2) p_odd[i] += a[i];
else p_even[i] += a[i];
}
vector<int> dp(n + 1, inf); dp[0] = 0;
for (int r = 2; r <= n; r+=2) {
for (int l = r-2; l >= 0; l-=2) {
int mid = (l+r)/2;
int vs = p_odd[mid] - p_odd[l],
ws = p_even[r] - p_even[mid];
if (vs <= v && ws <= w) dp[r] = min(dp[r], dp[l] + 1);
}
}
cout << (dp[n] == inf ? -1 : dp[n]);
}
หากมีข้อสงสัย comment ไว้ใต้ post ได้เลยนะครับ 🙇♂️🙇♂️
ศึกษาโจทย์เพิ่มเติมได้ที่ Fast X Fourier