Peso D codicioso

Peso

Enlace de tema: peso
Inserte la descripción de la imagen aquí

responder

Ideas

El problema requiere tomar tantas pesas como sea posible, por lo que debemos comenzar con la más pequeña.
Según el significado de la pregunta, existe una relación múltiple entre dos pesos cualesquiera, y el peso más pequeño se puede encontrar a partir de los pesos. Lo llamamos temporalmente la unidad de peso de los pesos.
El peso de otros pesos se puede expresar como la unidad de peso de varios pesos.

Para un contenedor, para quitar un peso, debe asegurarse de que su capacidad restante sea mayor o igual al peso. Con base en lo anterior, también podemos expresar la capacidad del contenedor como la unidad de peso de varios pesos, y la parte sobrante no podrá quitar ningún peso, por lo que se puede ignorar.

Sistema binario de Lenovo, expresamos el tipo de peso como sistema X y la capacidad del contenedor en el sistema X.

lograr

kind数组: Se utiliza para almacenar los tipos de pesos de modo que la capacidad se pueda expresar como un número basado en X.
digit数组: digit[i]= El número de pesos de este tipo que puede contener el contenedor. Usando la "unidad de peso de peso" mencionada anteriormente, cada contenedor grande se puede dividir en varios contenedores pequeños, que es la operación de préstamo en suma y resta.

En los cálculos reales, recorremos todos los pesos ordenados en orden ascendente. Para pesos w[i], busque el kind数组subíndice del tipo correspondiente al peso para encontrar digit数组la cantidad correspondiente digit[i]. Cuando no es digit[i]0, indica que la capacidad actual puede almacenar el peso; cuando digit[i]es 0, juzgue si se puede tomar prestado digit[i]Si el peso no es 0 después de pedir prestado, significa que el peso no se puede almacenar. Dado que el peso del peso se clasifica en orden ascendente, si el peso actual no se puede almacenar, todos los pesos posteriores tampoco se pueden almacenar. En este punto, puede finalizar directamente y generar la respuesta (no generar y luego juzgar).

Código AC

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(a, b) memcpy(a, b, sizeof(b))
#define INF (0x3f3f3f3f)
#define mod (ull)(1e9+7)
typedef pair<int, int> P;

namespace FastIO {
    const int bufsiz = 1 << 22;
    char buf[bufsiz];

    inline char getch() {
        static int tot;
        tot++;
        if (tot == bufsiz) {
            fread(buf, 1, bufsiz, stdin);
            tot = 0;
        }
        return buf[tot];
    }

    inline int read() {
        int x = 0;
        char c = getch();
        while (!isdigit(c))c = getch();
        while (isdigit(c))x = x * 10 + c - '0', c = getch();
        return x;
    }
}
using FastIO::read;
const int N = 1e5 + 10;
int n, m;
int digit[N];
int cap[N], w[N];
int kind[N], top;

bool check(int pos) {
    for (int i = pos + 1; i <= top; i++) {
        if (digit[i]) {
            digit[i]--;
            digit[pos] += kind[i] / kind[pos];
            return true;
        }
    }
    return false;
}

int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    n = read(), m = read();
    rep(i, 1, n) cap[i] = read();
    rep(i, 1, m)w[i] = read();
    sort(w + 1, w + m + 1);
    rep(i, 1, m) if (w[i] != w[i - 1]) kind[++top] = w[i];
    rep(i, 1, n) {
        for (int j = top; j >= 1; j--) {
            digit[j] += cap[i] / kind[j];
            cap[i] %= kind[j];
        }
    }
    int ans = 0;
    rep(i, 1, m) {
        rep(j, 1, top) {
            if (w[i] == kind[j]) {
                if (digit[j]) {
                    digit[j]--;
                    ans++;
                } else if (check(j)) {
                    digit[j]--;
                    ans++;
                }
                break;
            }
        }
    }
    printf("%d", ans);
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_45934120/article/details/107660703
Recomendado
Clasificación