Cod sursa(job #907428)

Utilizator sebii_cSebastian Claici sebii_c Data 7 martie 2013 22:33:41
Problema Zebughil Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.72 kb
#include <cstdio>
#include <cstring>

#include <algorithm>

using namespace std;

const int MAXN = 18;
const int MAXS = (1 << 17);

long long weight[MAXN];

long long maxSum[MAXS];
int minCount[MAXS];

bool check(int c1, int c2, long long s1, long long s2, long long w1)
{
    if (s2 == -1 || c1 > c2 || (c1 == c2 && s1 - w1 > s2))
        return true;
    return false;
}

int main()
{
    freopen("zebughil.in", "r", stdin);
    freopen("zebughil.out", "w", stdout);

    int t = 3;
    while (t--) {
        int N;
        long long max_weight;
        scanf("%d %lld", &N, &max_weight);
        for (int i = 0; i < N; ++i) 
            scanf("%lld", &weight[i]);

        memset(maxSum, -1, sizeof(maxSum));
        memset(minCount, 0, sizeof(minCount));

        maxSum[0] = max_weight;
        minCount[0] = 1;
        int max_num = (1 << N);
        for (int i = 1; i < max_num; ++i)
            for (int j = 0; j < N; ++j) {
                if ((i & (1 << j)) != 0) {
                    int prev = i ^ (1 << j);
                    if (maxSum[prev] >= weight[j]) {
                        if (check(minCount[i], minCount[prev], maxSum[prev], maxSum[i], weight[j])) {
                            maxSum[i] = maxSum[prev] - weight[j];
                            minCount[i] = minCount[prev];
                        }
                    } else if (maxSum[prev] < weight[j]) {
                        if (check(minCount[i], minCount[prev] + 1, max_weight, maxSum[i], weight[j])) {
                            maxSum[i] = max_weight - weight[j];
                            minCount[i] = minCount[prev] + 1;
                        }
                    }
                }
            }
        printf("%d\n", minCount[(1 << N) - 1]);
    }

    return 0;
}