# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1123249 | kiethm07 | Knapsack (NOI18_knapsack) | C11 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
#define pii pair<int,int>
#define pli pair<long long,pii>
#define fi first
#define se second
#define vi vector<int>
#define vii vector<pii>
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef long double ld;
const int inf = 2e9 + 5;
const ll linf = 1e16;
const double pi = acos(-1);
const int N = 1e5 + 5;
const int S = 2e3 + 5;
int n,s;
int dp[2][S];
int v[N], w[N], k[N];
vector<pii> f[S];
deque<pii> dq[S];
int ptr[S];
void build(int i){
bool pre = (i & 1) ^ 1;
for (int j = 0; j < w[i]; j++){
f[j].clear();
dq[j].clear();
ptr[j] = 0;
}
for (int j = 0; j <= s; j++){
int id = j % w[i];
f[id].push_back(pii(dp[pre][j] - v[i] * (j / w[i]),j));
}
}
int query(int x,int j){
int res = -inf;
int id = j % w[x];
// for (int i = 0; i < f[id].size(); i++){
// int tmp = (j - f[id][i].se) / w[x];
// if (tmp > k[x] || tmp < 0) continue;
// //cout << "Q: " << x << " " << j << " " << f[id][i].se << " " << j - f[id][i].se << " " << tmp << "\n";
// res = max(res, f[id][i].fi);
// }
int &i = ptr[id];
for (i; i < f[id].size(); i++){
while((!dq[id].empty()) && (j - dq[id].front().se) / w[x] > k[x]) dq[id].pop_front();
if (f[id][i].se > j) break;
while((!dq[id].empty()) && dq[id].back().fi <= f[id][i].fi) dq[id].pop_back();
dq[id].push_back(pii(f[id][i].fi,f[id][i].se));
}
if (!dq[id].empty()) res = max(res, dq[id].front().fi);
return res;
}
int main(){
#define TEXT "knapsack"
cin.tie(0) -> sync_with_stdio(0);
if (fopen(TEXT".inp","r")){
freopen(TEXT".inp","r",stdin);
freopen(TEXT".out","w",stdout);
}
cin >> s >> n;
for (int i = 1; i <= n; i++){
cin >> v[i] >> w[i] >> k[i];
}
for (int i = 1; i <= n; i++){
bool cur = i & 1;
bool pre = cur ^ 1;
build(i);
for (int j = 0; j <= s; j++){
dp[cur][j] = v[i] * (j / w[i]) + query(i,j);
// for (int x = 0; x <= k[i]; x++){
// int t = w[i] * x;
// if (t > j) break;
// dp[cur][j] = max(dp[cur][j], dp[pre][j - t] + v[i] * x);
// }
}
}
int res = 0;
for (int j = 0; j <= s; j++){
res = max(res, dp[n & 1][j]);
}
cout << res << "\n";
return 0;
}