C ++ - Problema de mochila de programación dinámica (1)

1. [Plantilla] 01 Mochila_Niuke Topic_Niuke.com

Tienes una mochila con un volumen máximo de V.

Ahora hay n elementos, el volumen del i-ésimo elemento es vivi​ y el valor es wiwi​.

(1) Encuentre el valor máximo de artículos que puede contener esta mochila.

(2) Si la mochila está exactamente llena , ¿cuánto valor puede contener como máximo?

Introduzca una descripción:

Los dos números enteros n y V en la primera línea representan el número de artículos y el volumen de la mochila.

Las siguientes n líneas, cada una con dos números vivi​y wiwi​, representan el volumen y el valor del i-ésimo artículo.

1≤n,V,vi,wi≤10001≤n,V,vi​,wi​≤1000

Descripción de salida:

El resultado tiene dos líneas. La primera línea genera la respuesta a la primera pregunta y la segunda línea genera la respuesta a la segunda pregunta. Si no hay solución, envíe 0.

Ejemplo 1

ingresar:

3 5 
2 10 
4 5 
1 4

producción:

14 
9

ilustrar:

El valor total se maximiza cuando se cargan el primer y tercer artículo, pero el segundo y tercer artículo se pueden llenar de modo que la mochila esté exactamente llena y se maximice el valor total.

Ejemplo 2

ingresar:

3 8 
12 6 
11 8 
6 8

producción:

8 
0

ilustrar:

Al cargar el tercer artículo, el valor total es el mayor pero no se satisface y no hay solución para llenar la mochila.

Análisis: Para el problema de la mochila, esta pregunta es muy importante, el proceso de análisis se muestra en la siguiente figura:

#include <iostream>
#include <string.h>
#include <vector>
#include <stdio.h>
using namespace std;
const int V=1010;//体积
int n=0;
int v=0;
int num[V];//体积
int val[V];//价值
int main()
{
    cin>>n;
    cin>>v;
    for(int i=0;i<n;i++)
    {      
        cin>>num[i]>>val[i];
    }   
    int dp[V];
    //第一题
    memset(dp,0,sizeof dp);//初始化
    for(int i=1;i<=n;i++)
    {
        for(int j=v;j>=num[i-1];j--)
        {
            dp[j] = max(dp[j],dp[j - num[i-1]] + val[i-1]);
        }
    }
    cout<<dp[v]<<endl;
    //第二题
    memset(dp,0,sizeof dp);
    for(int j = 1; j <= v; j++)
        dp[j] = -1;
    for(int i=1;i<=n;i++)
    {
        for(int j=v;j>=num[i-1];j--)
        {
            
            if(dp[j - num[i-1]] != -1)
                dp[j] = max(dp[j],dp[j - num[i-1]] + val[i-1]);
        }
    }
    cout << (dp[v] == -1 ? 0 : dp[v]) << endl;
    return 0;
}

2. Segmentación y subconjuntos  Sitio web oficial de LeetCode: la plataforma de crecimiento tecnológico amada por los geeks globales

Se le proporciona una matriz  no vacía que contiene solo números enteros positivos . Juzgue si esta matriz se puede dividir en dos subconjuntos para que la suma de los elementos de los dos subconjuntos sea igual.nums

Ejemplo 1:

Entrada: nums = [1,5,11,5]
 Salida: verdadero
 Explicación: La matriz se puede dividir en [1, 5, 5] y [11].

Ejemplo 2:

Entrada: nums = [1,2,3,5]
 Salida: false
 Explicación: La matriz no se puede dividir en subconjuntos iguales y de dos elementos.

Análisis: Para esta pregunta, el problema que hay que resolver es cómo convertirlo en un problema de mochila. Esta pregunta requiere dividir la matriz para que los tamaños de las dos submatrices sean iguales, para que podamos encontrar la suma de las elementos de la matriz, y luego divídalo por 2 para juzgar si es divisible, si no, devuelve falso; si es divisible por 2, se aplica el problema de la mochila:

class Solution {
public:
    bool canPartition(vector<int>& nums) 
    {
        int n=nums.size();
        int sum=0;
        for(const auto& s:nums) sum+=s;
        
        if(sum%2==1)
            return false;
        sum=sum/2;
        //初始化
        vector<bool> dp(sum+1);

        dp[0]=true;

        for(int i=1;i<=n;i++)
        {
            for(int j=sum;j>=nums[i-1];j--)
            {
                    dp[j]=dp[j]||dp[j-nums[i-1]];              
            }
        }
        return dp[sum];
    }
};

3. Sitio web oficial de Goal y  LeetCode: una plataforma de crecimiento tecnológico amada por los geeks globales

Se le proporciona una matriz de números enteros no negativos numsy un número entero target.

'+'Sumando o a cada número entero de la matriz  '-'y luego concatenando todos los números enteros, se puede construir una expresión :

  • Por ejemplo, nums = [2, 1]se puede 2agregar antes '+', 1agregar antes '-'y luego concatenar para obtener la expresión "+2-1".

Devuelve el número de expresionestarget distintas que se pueden construir mediante los métodos anteriores y que se evalúan como iguales a .

Ejemplo 1:

Entrada: números = [1,1,1,1,1], objetivo = 3
 Salida: 5
 Explicación: Hay 5 formas de hacer que el objetivo final sume 3. 
-1 + 1 + 1 + 1 + 1 = 3 
+1 - 1 + 1 + 1 + 1 = 3 
+1 + 1 - 1 + 1 + 1 = 3 
+1 + 1 + 1 - 1 + 1 = 3 
+1 + 1 + 1 + 1 - 1 = 3

Ejemplo 2:

Entrada: números = [1], objetivo = 1
 Salida: 1

analizar:

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) 
    {
        int sum=0;
        int n=nums.size();
        //转化为背包问题
        for(int i=0;i<n;i++) sum+=nums[i];
        if((sum+target)<0||(sum+target)%2) return 0;

        sum=(sum+target)/2;
        //初始化
        vector<int> dp(sum+1);
        dp[0]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=sum;j>=nums[i-1];j--)
            {
                 dp[j]+=dp[j-nums[i-1]];
            }
        }
        return dp[sum];
        
    }
};

4. El peso de la última piedra (2)  Sitio web oficial de LeetCode: la plataforma de crecimiento tecnológico amada por los geeks globales

Hay un montón de piedras, representadas por una serie de números enteros  stones. ¿ Dónde  stones[i]está iel peso de la primera piedra?

En cada turno, elige dos piedras cualesquiera de entre ellas y aplastalas. Supongamos que los pesos de las piedras son  xy, respectivamente  x <= y. Entonces los posibles resultados del aplastamiento son los siguientes:

  • Si  x == y, entonces ambas piedras están completamente trituradas;
  • Si  x != y, entonces  x una piedra de peso se hará añicos por completo, y  y una piedra de peso tendrá un nuevo peso de  y-x.

Al final, como máximo quedará una piedra . Devuelve el peso más pequeño posible para esta piedra . Si no quedan piedras, regresa 0.

Ejemplo 1:

Entrada: piedras = [2,7,4,1,8,1]
 Salida: 1
 Explicación: 
Combine 2 y 4 para obtener 2, por lo que la matriz se convierte a [2,7,1,8,1], 
combine 7 y 8, obtiene 1, entonces la matriz se convierte a [2,1,1,1], 
combina 2 y 1, obtiene 1, entonces la matriz se convierte a [1,1,1], 
combina 1 y 1, obtiene 0, por lo que la matriz se convierte a [1], que es el valor óptimo.

Ejemplo 2:

Entrada: piedras = [31,26,33,21,40]
 Salida: 5

analizar:

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) 
    {
        int sum=0;
        int n=stones.size();
        for(int i=0;i<n;i++) sum+=stones[i];
        int enquesum=sum;
        sum=sum/2;
        vector<int> dp(sum+1);
        for(int i=1;i<=n;i++)
        {
            for(int j=sum;j>=stones[i-1];j--)
            {
                dp[j]=max(dp[j],dp[j-stones[i-1]]+stones[i-1]);
            }
        }
        return enquesum-2*dp[sum];
    }
};

Supongo que te gusta

Origin blog.csdn.net/weixin_66828150/article/details/132568265
Recomendado
Clasificación