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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #include <bits/stdc++.h> #define int long long
using namespace std;
const int Maxn = 1000 + 10;
struct edge { int a, b, c, v; }A[Maxn];
struct point { int x, y; bool operator < (const point &a) const { unsigned int p = x; p *= y; unsigned int q = a.x; q *= a.y; return q == p ? x < a.x : p < q; } };
point Ans;
int N, M, MAX; int Dp[1000 + 10];
point save[1000 + 10];
inline point DP () { point now; now.x = now.y = 1e9; for (int i = 1; i <= MAX; ++i) Dp[i] = 0x3f3f3f3f3f3f3f3f; Dp[0] = 0; for (int i = 1; i <= N; ++i) { for (int j = MAX; j >= A[i].v; --j) { if (Dp[j] > Dp[j - A[i].v] + A[i].c) { Dp[j] = Dp[j - A[i].v] + A[i].c; save[j].x = save[j - A[i].v].x + A[i].a; save[j].y = save[j - A[i].v].y + A[i].b; } } } int k = M; for (int i = M; i <= MAX; ++i) if (Dp[k] > Dp[i]) k = i; now = save[k]; if (now < Ans) Ans = now; return now; }
inline int mul (point a, point b, point c) { return (c.y - a.y) * (b.x - a.x) - (c.x - a.x) * (b.y - a.y); }
inline void Solve (point a, point b) { for (int i = 1; i <= M; ++i) A[i].c = A[i].b * (a.x - b.x) + A[i].a * (b.y - a.y); point c = DP(); if (mul(a, b, c) <= 0) return ; Solve (a, c); Solve (c, b); }
inline void Init () { Ans.x = Ans.y = 1e9; MAX = 0; memset(save, 0, sizeof save); }
main() { #ifdef hk_cnyali freopen("A.in", "r", stdin); freopen("A.out", "w", stdout); #endif while (~scanf("%lld%lld", &N, &M)) { Init(); for (int i = 1; i <= N; ++i) scanf("%lld%lld%lld", &A[i].v, &A[i].a, &A[i].b), MAX += A[i].v; for (int i = 1; i <= N; ++i) A[i].c = A[i].a; point a = DP(); for (int i = 1; i <= N; ++i) A[i].c = A[i].b; point b = DP(); Solve (b, a); printf("%lld\n", Ans.x * Ans.y); } return 0; }
|