1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| #include <cstdio> #include <cstring> #define maxN 1000010 struct stack{ int k, b; } p[60][2010]; int size[60], val[maxN], c[maxN], f[maxN]; int min (int x, int y) { return x < y ? x : y; } int change (int x, int y) { return x * (x - 1) / 2 + (y + 1); } int calc (int k, int x, int b) { return k * x + b; } int check (int k, int b, int kk, int bb) { return (bb - b) / (k - kk); } int main () { int n = 0, maxC = 0; scanf("%d %d", &n, &maxC); for(int i = 0;i < n; i++) { scanf("%d %d", &c[i], &val[i]); } memset(f, 127 / 3, sizeof(f)); const int inf = f[0]; f[0] = 0; int x = c[0], y = 0; int z = change(x, y); p[z][++size[z]].k = val[0]; for(int i = 1;i <= n; i++) { for(int j = 1;j <= maxC; j++) { int x = j, y = i % j; int z = change(x, y); int &N = size[z]; if(!N) { continue; } if(N > 1 && calc(p[z][N].k, i / j, p[z][N].b) >= calc(p[z][N - 1].k, i / j, p[z][N - 1].b)) { N--; } f[i] = min(f[i], calc(p[z][N].k, i / j, p[z][N].b)); } if(f[i] == inf || i == n) { continue; } int x = c[i], y = i % c[i]; int z = change(x, y); int &N = size[z]; while(N && p[z][N].k >= val[i]) { N--; } int k = val[i]; int b = f[i] - (i / c[i]) * val[i]; while(N > 1 && check(p[z][N - 1].k, p[z][N - 1].b, p[z][N].k, p[z][N].b) <= check(p[z][N].k, p[z][N].b, k, b)) { N--; } N++; p[z][N].k = k, p[z][N].b = b; } for(int i = 1;i <= n; i++) { printf("%d ", f[i] == inf ? -1 : f[i]); } return 0; }
|