Picking Medicine (Detailed Explanation Version of 01 Backpack Two-dimensional Array||One-dimensional Array)

vjudge submit link

Topic: Collecting Medicine

——Chenchen is a gifted child. His dream is to become the greatest physician in the world. For this reason, he wanted to worship the most prestigious physician nearby as his teacher. In order to judge his aptitude, the doctor presented him with a difficult problem. The doctor took him to a cave full of herbs and said to him: "My child, there are some different herbs in this cave. It takes some time to pick each plant, and each plant has its own value. I will give it to him. You can gather some herbs during this period of time. If you are a smart child, you should be able to maximize the total value of the herbs you gather." If you are Chenchen, you can complete this task. ?

Input ——The
first line of input has two integers T (1 <= T <= 1000) and M (1 <= M <= 10), separated by a space, T represents the total time that can be used to gather the medicine, M represents the number of herbs in the cave. Each of the next M lines contains two integers between 1 and 100 (including 1 and 100), which respectively indicate the time to pick a certain herb and the value of this herb.

Output ——The
output includes one line. This line only contains an integer, which represents the maximum total value of herbs that can be collected within a specified time.

Sample Input
70 3
71 100
69 1
1 2

Sample Output
3

Problem-solving ideas:

01 Detailed explanation of the process of backpacking two-dimensional arrays , you will not regret after reading it , as long as you can build a table, your thinking will be super clear.

Code:

#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;
}

Optimize space complexity

——Change for(j=1;j<=t;j++) to change for(j=t;j>0;j--) to a one-dimensional array

Code:

#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;
}

Can not watch

Problem-solving ideas:

State transition equation: dp[j]=max(dp[j],dp[jp[i]]+w[i]);
dp[j] represents the maximum value that can be obtained in j time

Initially: the possession time is t, and the herbal value is 0 to
maximize the value of the herbal medicine in hand. Using dp thinking
dp thinking: In the current situation, to judge whether the behavior is feasible or unfeasible, keep the data if it is feasible, and not keep the data if it is not feasible.
So when facing a herbal medicine, the first thing to do is to judge whether it is cost-effective to pick it, and to judge according to the state transition equation

Given a set of data:
t=5, the picking time and value of 2 kinds of herbs are given below
3 5
4 6

3 5: As long as the time j>=3 in the hand, the value can be obtained, so dp[3]=dp[4]=dp[5]=5;
4 6: As long as the time in the hand 4<= j<7, then according to the state transition equation, dp[4]=dp[5]=6
Obviously this herbal medicine is more valuable. After the herbal medicine is picked, the remaining time jp[i]=0 is not enough to pick it.
If the time for the first herb is t=7, after picking the second herb, the remaining time jp[i]=3, the first herb can still be picked, so dp[7]=6+5 =11

Review 01 backpack 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]);
} 

When facing the i-th herb and can pick it, the current possession time is j.
Now we have to consider whether it is worth picking, and whether the current dp[j] can be made larger.
One is not to pick: dp[j] The current value remains unchanged. The other
is to pick: dp[jp[i]] +w[i] The value of the herb + the remaining time to obtain the value.
If dp[j] becomes smaller after picking, it means that it is not cost-effective to pick the herb under the current situation.
If dp[j] becomes larger after picking , Which shows that picking is cost-effective under the current circumstances

Note: dp is an array, which is optimal in many cases.

Guess you like

Origin blog.csdn.net/Helinshan/article/details/114743405