638. Paquete de regalo

En la tienda LeetCode, hay muchos artículos a la venta.

Sin embargo, también hay algunos paquetes de regalo, y cada paquete de regalo incluye un conjunto de artículos a un precio favorable.

Dado el precio de cada artículo, cada paquete de regalo contiene una lista de artículos y una lista de artículos que se comprarán. Indique el costo mínimo exacto para completar la lista pendiente.

Cada paquete de regalo se describe mediante un conjunto de datos en una matriz, el último número representa el precio del paquete de regalo y los otros números indican el número de otros tipos de artículos contenidos.

Cualquier paquete de regalo se puede comprar ilimitadamente.

Ejemplo 1:

Entrada: [2,5], [[3,0,5], [1,2,10]], [3,2]
Salida: 14
Explicación:
Hay dos elementos A y B, el precio es ¥ 2 y ¥ 5.
Spree 1, puedes comprar 3A y 0B por ¥ 5.
Spree 2, puedes comprar 1A y 2B por ¥ 10.
Necesita comprar 3 A y 2 B, por lo que pagó ¥ 10 para comprar 1A y 2B (Paquete de regalo 2) y ¥ 4 para comprar 2A.
Ejemplo 2

Entrada: [2,3,4], [[1,1,0,4], [2,2,1,9]], [1,2,1]
Salida: 11
Explicación:
A, B, C Los precios son de ¥ 2, ¥ 3, ¥ 4.
Puede comprar 1A y 1B con ¥ 4, o puede comprar 2A, 2B y 1C con ¥ 9.
Debe comprar 1A, 2B y 1C, por lo que pagó ¥ 4 por 1A y 1B (Paquete de regalo 1), y ¥ 3 por 1B y ¥ 4 por 1C.
No puede comprar artículos que están más allá de la lista de compras, aunque es más barato comprar la juerga 2.

Nota:
hasta 6 artículos y 100 paquetes de regalo.
Para cada artículo, solo necesita comprar un máximo de 6.
No puede comprar artículos que están más allá de la lista para comprar, incluso si son más baratos.

Fuente: LeetCode


¿Qué dice esta pregunta, aunque se ha escrito durante aproximadamente una hora, en realidad es una cuestión de pensamiento independiente y finalización en la escuela secundaria?
Escriba rápidamente sobre la formación de
esta pregunta : 1. Esta pregunta debe ser recursiva. ¿Cómo resolver la recursividad?
2. Austria, debe enumerar todas las soluciones posibles de forma recursiva y encontrar la respuesta más pequeña.
3. ¿Cómo escribir varios elementos de recursión?

  • Condición final: no se puede comprar más, solo tiene que estar en lo cierto. Más tarde, se desarrolló para no tener excedentes (todo lo que desea comprar).
    Hay un proceso en el medio, pensando en este problema recursivo a resolver : simplemente compre todo . Pensar aquí es una comprensión repentina, por lo que la condición final debe ser que las cosas estén compradas. Al principio pensé en la condición final de la recursión, pero no pensé en el problema real resuelto por esta recursividad. Desviado de la realidad. Piénselo la próxima vez, hasta qué punto lo hice antes de no hacerlo .
  • Asunto: el tema debe estar de compras
    • Primero compre una juerga y luego compre un solo producto.
    • Compre una juerga para ver si puede comprarla. Puede comprar, recursivo; no puede comprar, vea el próximo gran paquete de regalo.
    • Finalmente, verifique si hay vacantes faltantes y compre los artículos no vendidos.
    • Dudando después de escribir, debe ser el 优先级 (当时理解成代码的执行顺序 )mismo que el paquete de regalo, y debe estar armado. Luego lo pensé nuevamente, el paquete de regalo debe ser descontado.

4. Finalmente encontró que la respuesta es incorrecta, piense que resultó que la variable del medio es incorrecta (ans- = especial [i] [j]; no existe tal línea). Cambió y tuvo éxito.
Finalmente, con respecto al problema de prioridad, agregue ans- = special [i] [j], y luego piense en ello, entonces la prioridad es la misma. El entendimiento ahora es que todos tienen la oportunidad de comprarlo.
O simplemente cámbialo dfs(price,special,needs,ans+special[i][j]).

int eans=0x3f3f3f3f;
    int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {
      
        dfs(price,special,needs,0);
        return eans;
    }
    void dfs(vector<int>& price, vector<vector<int>>& special, vector<int>& needs,int ans){
        int flag=0;
        for(auto a:needs){
            flag+=a;
        }
        if(flag==0){
            eans=min(ans,eans);
            return;
        } 
        //需要的  都  买完了。所以结束递归,返回价钱。

        //开始买大礼包
        for(int i=0;i<special.size();i++){
            //看看大礼包能不能买,不能买的的话,看下一个大礼包
            int flag1=true;
            int j;
            for(j=0;j<needs.size();j++){
                if(special[i][j]>needs[j]) {
                    flag1=false;
                    break;
                }
            }

            //要是可以买大礼包,则递归
            if(flag1){
                ans+=special[i][j];//把大礼包的价钱加上
                for(j=0;j<special[i].size()-1;j++) needs[j]-=special[i][j];//把需求减去
                dfs(price,special,needs,ans);//继续看下一个礼包,
                //递归之后,需要需求加回来
                for(j=0;j<special[i].size()-1;j++) needs[j]+=special[i][j];
                ans-=special[i][j];//把大礼包的价钱减去
            }
        }
        //大礼包买完了,开始买单价商品
        vector<int>tep=needs;
        int tepp=0;
        for(int i=0;i<needs.size();i++){
            if(needs[i]!=0){
                tepp+=needs[i]*price[i];
                needs[i]=0;
            }
        }
        ans+=tepp;
        //cout<<ans<<endl;
        dfs(price,special,needs,ans);
        needs=tep;
        ans-=tepp;
    }
161 artículos originales publicados · Me gusta 68 · Visitantes más de 20,000

Supongo que te gusta

Origin blog.csdn.net/qq_43179428/article/details/104310922
Recomendado
Clasificación