#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
using namespace std;
typedef long long ll;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int s, n;
    cin >> s >> n;
    vector<ll> dp(s + 1, 0); // dp[j]: best value for capacity j
    // Process each item one by one.
    for (int i = 0; i < n; ++i) {
        int price, weight, count;
        cin >> price >> weight >> count;
        
        // If the item weight is larger than our knapSack capacity, skip.
        if (weight > s) continue;
        
        // We cannot use more than s/weight copies
        count = min(count, s / weight);
        // Process each residue modulo weight.
        // For every r (0 <= r < weight), j takes the form j = r + k * weight.
        for (int r = 0; r < weight; r++) {
            deque<int> dq;
            // k is the number of items used (0-indexed) along this residue.
            // j = r + k*weight must be within [0, s].
            for (int k = 0; r + k * weight <= s; k++) {
                int j = r + k * weight;
                
                // Value we want to optimize: 
                // f(k) = dp[j] - k * price.
                ll cur = dp[j] - (ll)k * price;
                
                // Remove indices from the front that are out of the allowed range (k - previous_index > count)
                while (!dq.empty() && dq.front() < k - count)
                    dq.pop_front();
                
                // Maintain the deque in decreasing order of dp[r + (index)*weight] - index*price.
                while (!dq.empty() && (dp[r + dq.back() * weight] - (ll)dq.back() * price) <= cur)
                    dq.pop_back();
                
                dq.push_back(k);
                
                // Update dp[j] using the best candidate from the deque.
                // Let t = dq.front(). Then for j = r + k*weight, we get:
                // dp[j] = dp[r + t*weight] + (k - t) * price.
                dp[j] = dp[r + dq.front() * weight] + (ll)(k - dq.front()) * price;
            }
        }
    }
    
    cout << dp[s] << "\n";
    return 0;
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |