Picking Medicine (versão com explicação detalhada de 01 mochila Two-dimensional Array || One-dimensional Array)

vjudge enviar link

Tópico: Coletando Remédios

—— Chenchen é uma criança talentosa. Seu sonho é se tornar o maior médico do mundo. Por esta razão, ele queria adorar o médico de maior prestígio nas proximidades como seu professor. Para julgar sua aptidão, o médico apresentou-lhe um problema difícil. O médico levou-o a uma caverna cheia de ervas e disse-lhe: “Meu filho, tem algumas ervas diferentes nesta caverna. Demora um pouco para colher cada planta, e cada planta tem o seu valor. ele. Você pode colher algumas ervas durante este período de tempo. Se você for uma criança inteligente, você deve ser capaz de maximizar o valor total das ervas que você coleta. "Se você for Chenchen, você pode completar esta tarefa."

Entrada —— A
primeira linha de entrada tem dois inteiros T (1 <= T <= 1000) e M (1 <= M <= 10), separados por um espaço, T representa o tempo total que pode ser usado para reunir o medicamento, M representa o número de ervas na caverna. Cada uma das próximas M linhas contém dois números inteiros entre 1 e 100 (incluindo 1 e 100), que indicam respectivamente a hora de escolher uma determinada erva e o valor da erva.

Saída —— A
saída inclui uma linha. Esta linha contém apenas um número inteiro, que representa o valor total máximo de ervas que podem ser coletadas dentro de um tempo especificado.

Amostra de entrada
70 3
71 100
69 1
1 2

Saída de amostra
3

Ideias para resolução de problemas:

01 Explicação detalhada do processo de mochila de arrays bidimensionais , você não vai se arrepender depois de lê-la , contanto que você consiga construir uma mesa, seu pensamento será super 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;
}

Otimize a complexidade do espaço

—— Altere para (j = 1; j <= t; j ++) para alterar para (j = t; j> 0; j--) para uma 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;
}

Não posso assistir

Ideias para resolução de problemas:

Equação de transição de estado: dp [j] = max (dp [j], dp [jp [i]] + w [i]);
dp [j] representa o valor máximo que pode ser obtido no tempo j

Inicialmente: o tempo de posse é t, e o valor do fitoterápico é 0 para
maximizar o valor do fitoterápico em mãos. Usando pensamento
dp pensamento dp: Na situação atual, para julgar se o comportamento é viável ou inviável, guarde os dados se é viável, e não guarda os dados se não for viável.
Portanto, ao enfrentar um medicamento fitoterápico, a primeira coisa a fazer é julgar se é rentável colhê-lo e julgar de acordo com a equação de transição de estado

Dado um conjunto de dados:
t = 5, o tempo de colheita e o valor de 2 tipos de ervas são dados abaixo de
3 5
4 6

3 5: Enquanto o tempo j> = 3 no ponteiro, o valor pode ser obtido, então dp [3] = dp [4] = dp [5] = 5;
4 6: Enquanto o tempo no mão 4 <= j <7, então de acordo com a equação de transição de estado, dp [4] = dp [5] = 6
Obviamente, este fitoterápico é mais valioso. Depois que o fitoterápico é colhido, o tempo restante jp [i] = 0 não é suficiente para colhê-la.
Se o tempo para a primeira erva for t = 7, depois de colher a segunda erva, o tempo restante jp [i] = 3, a primeira erva ainda pode ser colhida, então dp [7] = 6 + 5 = 11

Revise 01 núcleo de mochila

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

Ao enfrentar a i-ésima erva e puder colhê-la, o tempo de posse atual é j.
Agora temos que considerar se vale a pena escolher, e se o atual dp [j] pode ser aumentado.
Um não é escolher: dp [j] O valor atual permanece inalterado. O outro
é escolher: dp [jp [ i]] + w [i] O valor da erva + o tempo restante para obter o valor.
Se dp [j] ficar menor após a colheita, significa que não é custo-efetivo colher a erva na situação atual.
Se dp [j] se torna maior após a separação, o que mostra que a separação é econômica nas circunstâncias atuais

Nota: dp é um array, o que é ótimo em muitos casos.

Acho que você gosta

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