luoguP2329 [SCOI2005] Fence

First, we can see a nature: take smaller than some of the big bad take.Well obviously

So we will be required to John planks from small to large, raw materials, but also from small to large order, then half a \ (mid \) represents John takes a few planks, with a search \ (check \) click.

Several pruning:

  • A. We can define a global variable \ (Waste \) indicates the length of the cut wood raw material in total waste.

    \ (\ THEREFORE \) if \ (Waste + \ sum_. 1 = {I}} ^ {MID B_i> \ SUM) , exit, returns \ (0 \) .

  • II. For two equal length required for wood, we can write a \ (last \) indicates the required board before found the first \ (last \) a, \ (\ THEREFORE \) directly from the \ (last \) you can start looking.

  • Third, we can sum is greater than in the first two minutes ago \ (SUM \) is omitted, i.e. \ (while (s [r] > sum) - r; \)

#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
using namespace std;
template<class TT>
il TT read() {
    TT o = 0,fl = 1; char ch = getchar();
    while (!isdigit(ch) && ch != '-') ch = getchar();
    if (ch == '-') fl = -1, ch = getchar();
    while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
    return fl * o;
}
int n, m, sum, l, r, mid, t, ans, a[55], b[1005], c[55], s[1005];
bool check(int x, int last) {
    if (!x) return true;
    if (sum < t + s[mid]) return false;
    for (int i = last; i <= m; ++i) {
        if (c[i] >= b[x]) {
            c[i] -= b[x];
            if (c[i] < b[1]) t += c[i];
            if (b[x] == b[x - 1]) {
                if (check(x - 1, last)) return true;
            }
            else if (check(x - 1, 1)) return true;
            if (c[i] < b[1]) t -= c[i];
            c[i] += b[x];
        }
    }
    return false;
}
int main() {
    m = gi();
    for (int i = 1; i <= m; ++i)
        a[i] = gi(), sum += a[i];
    sort(a + 1, a + m + 1);
    n = gi();
    for (int i = 1; i <= n; ++i) b[i] = gi();
    sort(b + 1, b + n + 1);
    for (int i = 1; i <= n; ++i) s[i] = s[i - 1] + b[i];
    l = 1, r = n;
    while (s[r] > sum) --r;
    while (l <= r) {
        for (int i = 1; i <= m; ++i) c[i] = a[i];
        mid = l + r >> 1, t = 0;
        if (check(mid, 1)) ans = mid, l = mid + 1;
        else r = mid - 1;
    }
    printf("%d\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/lylyl/p/11762233.html