[BZOJ1531] [POI2005] Bank notes [單調佇列][多重揹包]
阿新 • • 發佈:2018-12-20
把樸素多重揹包的式子稍作轉化,得到: (列舉) 看了半天感覺不太對結果發現這道題也是代價等於價值,,
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
int n, m;
int a[205];
int c[205];
pair<int, int> q[20005];
int qh, qt;
int f[20005];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= n; ++i) {
scanf("%d", &c[i]);
}
scanf("%d", &m);
memset(f, 0x3f, sizeof(f));
f[0] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < a[i]; ++j) {
qh = 1;
qt = 0;
for (int x, k = 0; ; ++k) {
if ((x = k * a[i] + j) > m) break;
while (qh <= qt && q[qh].second < k - c[i]) {
++qh;
}
while (qh <= qt && q[qt].first >= f[x] - k) {
--qt;
}
q[++qt] = make_pair(f[x] - k, k);
f[x] = min(f[x], q[qh].first + k);
}
}
}
printf("%d", f[m]);
return 0;
}