Picking Medicine (Explicación detallada Versión de 01 Mochila Matriz bidimensional || Matriz unidimensional)

vjudge enviar enlace

Tema: Recolección de medicina

——Chenchen es un niño superdotado y su sueño es convertirse en el mejor médico del mundo. Por esta razón, quería adorar al médico más prestigioso de la zona como su maestro. Para juzgar su aptitud, el médico le presentó un problema difícil. El médico lo llevó a una cueva llena de hierbas y le dijo: "Hijo mío, hay algunas hierbas diferentes en esta cueva. Se necesita un tiempo para recoger cada planta, y cada planta tiene su propio valor. Se lo daré a él. Puedes recolectar algunas hierbas durante este período de tiempo. Si eres un niño inteligente, deberías poder maximizar el valor total de las hierbas que recolectas. "Si eres chencheno, puedes completar esta tarea.?

Entrada: la
primera línea de entrada tiene dos números enteros T (1 <= T <= 1000) y M (1 <= M <= 10), separados por un espacio, T representa el tiempo total que se puede usar para recopilar el medicina, M representa el número de hierbas en la cueva. Cada una de las siguientes M líneas contiene dos números enteros entre 1 y 100 (incluidos 1 y 100), que indican respectivamente el momento de recoger una determinada hierba y el valor de la hierba.

Salida: la
salida incluye una línea. Esta línea solo contiene un número entero, que representa el valor total máximo de hierbas que se pueden recolectar dentro de un tiempo específico.

Entrada de muestra
70 3
71100
69 1
1 2

Salida de muestra
3

Ideas de resolución de problemas:

01 Explicación detallada del proceso de mochilero de matrices bidimensionales , no te arrepentirás después de leerlo , siempre que puedas construir una mesa, tu pensamiento será súper claro.

Código:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int T=1010;
const int M=11;
int dp[M][T];//构建一个M*T的表格,m行草药,T列的容量。
int p[M],w[M];
//dp[i][j]表示前i件草药恰好放入一个容量为j的背包可以获得的最大价值
int main()
{
	int t,m,i,j;
	while(~scanf("%d %d",&t,&m))
	{
		memset(dp,0,sizeof(dp));
		for(i=1;i<=m;i++)
		{
			//其实scanf("%d %d",&p,&w);就行
			scanf("%d %d",&p[i],&w[i]);
			for(j=1;j<=t;j++)
			{
				if(j<p[i])//不能采 
					dp[i][j]=dp[i-1][j]; 
				else
					dp[i][j]=max(dp[i-1][j],dp[i-1][j-p[i]]+w[i]);		
			}	
		}
		printf("%d\n",dp[m][t]);
	}
	return 0;
}

Optimiza la complejidad del espacio

——Cambie por (j = 1; j <= t; j ++) para cambiar por (j = t; j> 0; j--) a una matriz unidimensional

Código:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[1010];//dp[i]表示在时间i内能获得的最大价值  
int p[20],w[20];
int main()
{
	int t,m,i,j;
	while(~scanf("%d %d",&t,&m))
	{
		memset(dp,0,sizeof(dp));
		for(i=1;i<=m;i++)
		{
			//其实scanf("%d %d",&p,&w);就行
			scanf("%d %d",&p[i],&w[i]);
			for(j=t;j>=p[i];j--)
				dp[j]=max(dp[j],dp[j-p[i]]+w[i]);
		} 
		printf("%d\n",dp[t]);
	}
	return 0;
}

No puedo mirar

Ideas de resolución de problemas:

Ecuación de transición de estado: dp [j] = max (dp [j], dp [jp [i]] + w [i]);
dp [j] representa el valor máximo que se puede obtener en j tiempo

Inicialmente: el tiempo de posesión es t, y el valor a base de hierbas es 0 para
maximizar el valor de la medicina a base de hierbas en la mano. Usando el pensamiento
dp pensamiento dp: En la situación actual, para juzgar si el comportamiento es factible o inviable, mantenga los datos si es factible, y no conservar los datos si no es factible.
Entonces, cuando se enfrenta a un medicamento a base de hierbas, lo primero que debe hacer es juzgar si es rentable elegirlo y juzgar de acuerdo con la ecuación de transición estatal

Dado un conjunto de datos:
t = 5, el tiempo de recolección y el valor de 2 tipos de hierbas se dan a continuación
3 5
4 6

3 5: Siempre que el tiempo j> = 3 en la mano, se puede obtener el valor, entonces dp [3] = dp [4] = dp [5] = 5;
4 6: Siempre que el tiempo en el mano 4 <= j <7, luego de acuerdo con la ecuación de transición de estado, dp [4] = dp [5] = 6
Obviamente, esta medicina herbal es más valiosa. Después de que se escoge la medicina herbal, el tiempo restante jp [i] = 0 no es suficiente para recogerla.
Si el tiempo para la primera hierba es t = 7, después de recoger la segunda hierba, el tiempo restante jp [i] = 3, la primera hierba todavía se puede recoger, entonces dp [7] = 6 + 5 = 11

Revisión 01 mochila core

for(i=0;i<m;i++)
{
	for(j=t;j>=p[i];j--)
		dp[j]=max(dp[j],dp[j-p[i]]+w[i]);
} 

Cuando se enfrenta a la hierba i-ésima y puede recogerla, el tiempo de posesión actual es j.
Ahora tenemos que considerar si vale la pena elegir, y si el dp [j] actual se puede hacer más grande.
Uno no es elegir: dp [j] El valor actual permanece sin cambios. El otro
es elegir: dp [jp [ i]] + w [i] El valor de la hierba + el tiempo restante para obtener el valor
Si dp [j] se reduce después de la recolección, significa que no es rentable recolectar la hierba en la situación actual.
Si dp [j] aumenta después de realizar el picking, lo que muestra que el picking es rentable en las circunstancias actuales

Nota: dp es una matriz, que es óptima en muchos casos.

Supongo que te gusta

Origin blog.csdn.net/Helinshan/article/details/114743405
Recomendado
Clasificación