luoguP2329 [SCOI2005]フェンス

大きな悪いテイクの一部よりも小さいを取る:第一に、私たちは自然を見ることができます。まあ、明らかに

だから我々は、小規模から大規模、原材料にジョンの板に必要とするだけでなく、小規模から大規模なために、その後、半分されます\(中旬\)がジョンを表し、検索して、いくつかの厚板を取り、\(\チェック)をクリックします。

いくつかの剪定:

  • A.私たちは、グローバル変数を定義することができます\(廃\)総廃棄物で切断された木材原料の長さを示します。

    \(\したがって\)であれば\(廃棄物+ \ sum_。1 = {I}} ^ {MID B_i> \ SUM) 出口、戻り\(0 \)

  • II。木材のために必要な2つの同じ長さのために、我々は書くことができます(最後の\)\を前に見つかった必要なボードを示す第1 \(最後の\) A、\(\そのために\)から直接、\(最後の\)あなたが探し始めることができます。

  • 第三に、我々は、合計することができ最初の2分前により大きい\(SUM \) すなわち、省略されている(一方、(S [R] \ >和) - 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;
}

おすすめ

転載: www.cnblogs.com/lylyl/p/11762233.html