DP de mochila (Knapsack)
| Hecho | Fuente | Nombre | Dificultad | Tags | Solución |
|---|---|---|---|---|---|
| CSES | ★ Dice Combinations | Muy fácil | DP, Knapsack | en el módulo |
Tutorial
| Fuente | Recurso | Notas |
|---|---|---|
| CPH | 7.1, 7.4 - Coin, Knapsack Problems | Resuelve “Minimizing Coins” y la mochila 0/1 |
| YouTube | Errichto DP #2 - Coin change, double counting | Videos de las variantes habituales de mochila |
Los problemas de mochila (knapsack) suelen consistir en llenar un recipiente limitado con un subconjunto de ítems, de modo que se cuente u optimice alguna cantidad asociada a esos ítems. Casi siempre se puede pensar que cada ítem tiene un peso positivo, y que el peso total de los ítems que elijamos no puede exceder la capacidad del recipiente, que es un número. Algunas variantes de problemas tipo mochila son:
- El problema de la mochila 0/1 : elegir un subconjunto de ítems que maximice el valor total sin que el peso total exceda la capacidad del recipiente
- Hallar todos los pesos totales posibles que se pueden alcanzar con cualquier subconjunto de ítems cuyo peso total no exceda la capacidad del recipiente (en el capítulo de CPH enlazado arriba)
- Contar cuántas secuencias de ítems llenan el recipiente por completo, es decir, que el peso total sea exactamente la capacidad del recipiente (el orden puede o no importar)
La solución de DP de los problemas de mochila suele tener un estado que registra la capacidad de la mochila, y las transiciones consisten en intentar agregar un ítem. En programación competitiva es de esperar que los problemas clásicos de mochila vengan con giros, disfraces e información extra en el estado.
Solución - Dice Combinations
Complejidad temporal:
El problema pide cuántas secuencias de tiradas de dado existen tales que la suma de las caras superiores sea (). Siguiendo la analogía de la mochila, tenemos infinitos ítems de pesos a , y queremos contar cuántas secuencias de ítems existen de modo que, si los ponemos en el recipiente siguiendo la secuencia, el recipiente quede completamente lleno. Nótese que en este problema el orden de los ítems importa.
Por comodidad, sea la cantidad de secuencias de tiradas de dado que suman . Para contar cuántas secuencias suman , o sea, para hallar , miremos la última tirada que nos lleva a una suma total de .
Si la última tirada fue un , hay formas de alcanzar la suma cuando la última tirada es . Si la última tirada fue un , hay formas de alcanzar la suma cuando la última tirada es . Continuamos esta lógica para todos los números del dado hasta . Considerando todos esos casos juntos, queda demostrado que
Aplicamos la misma lógica que usamos para a un general:
Empezamos con el caso base , y después , , , y así sucesivamente… se pueden calcular con la recurrencia hasta hallar . Nótese en el código que ignoramos si .
#include <bits/stdc++.h>
using namespace std;
long long dp[1000001];
int main() {
int n;
cin >> n;
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 6; j++) {
if (i - j >= 0) { dp[i] += dp[i - j]; }
}
dp[i] %= 1000000007;
}
cout << dp[n] << "\n";
}
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n;
n = Integer.parseInt(br.readLine());
long dp[] = new long[n + 1];
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 6; j++) {
if (i - j >= 0) { dp[i] += dp[i - j]; }
}
dp[i] %= 1000000007;
}
System.out.println(dp[n]);
}
}dp = [1]
for i in range(int(input())):
dp.append(sum(dp[-6:]) % (10**9 + 7))
print(dp[-1])Problemas
Generales
| Hecho | Fuente | Nombre | Dificultad | Tags | Solución |
|---|---|---|---|---|---|
| CSES | ★ Minimizing Coins | Muy fácil | Knapsack | Solución | |
| CSES | ★ Coin Combinations I (Unordered) | Fácil | Knapsack | Solución | |
| CSES | ★ Coin Combinations II (Ordered) | Fácil | Knapsack | Solución | |
| AC | Subset Sum Queries | Fácil | Knapsack | Solución | |
| CSES | Book Shop | Fácil | Knapsack | Solución | |
| CSES | Money Sums | Fácil | Knapsack | Solución | |
| CSES | Two Sets II | Fácil | Knapsack | Solución | |
| CF | The Values You Can Make | Fácil | Knapsack | Solución | |
| NOI | Knapsack | Normal | DP, Knapsack | Solución | |
| CSES | Coding Company | Difícil | Knapsack | Solución |
USACO
| Hecho | Fuente | Nombre | Dificultad | Tags | Solución |
|---|---|---|---|---|---|
| Gold | Fruit Feast | Fácil | DP, Knapsack | Solución | |
| Gold | Talent Show | Normal | DP, Knapsack, Binary Search | Solución | |
| Gold | Bribing Friends | Difícil | DP, Greedy | Solución | |
| Platinum | Mooriokart | Muy difícil | Knapsack | Solución |
Teoría de números
¡Algunos problemas de mochila con giros de teoría de números!
| Hecho | Fuente | Nombre | Dificultad | Tags | Solución |
|---|---|---|---|---|---|
| CF | Round Subset | Normal | Knapsack | — | |
| Gold | Cow Poetry | Normal | Knapsack, Exponentiation | Solución | |
| Gold | Exercise | Normal | Knapsack, Prime Factorization | Solución | |
| POI | 2004 - Maximal | Normal | Knapsack, Prime Factorization | Solución | |
| CEOI | Cloud Computing | Difícil | Knapsack, Sorting | Solución | |
| Platinum | Exercise | Insano | Knapsack, Prime Factorization | Solución |