Course selection problem (dynamic programming)

Reprinted: C++ sword refers to offer: the dependent knapsack problem on the tree-shaped DP tree-course selection

topic

description

The school implements a credit system. Each compulsory course has a fixed number of credits, and the corresponding elective course credits must be obtained at the same time. The school offers N elective courses, and the number of courses each student can choose M is given. Students who take this M course and pass the assessment will get corresponding credits. Among the elective courses, some courses can be taken directly, and some courses require certain basic knowledge, which can only be taken on the basis of other courses. For example, "Frontpage" must be selected after "Windows Operating Basics". We call "Basics of Windows Operation" a prerequisite for "Frontpage". There is at most one direct prerequisite for each course. Two courses may also have the same prerequisites. Each course has a course number, which is 1, 2, 3,.... E.g:

 

In the table, 1 is the prerequisite for 2 and 2 is the prerequisite for 3 and 4. If you want to choose 3, then both 1 and 2 must have been chosen. Your task is to determine a course selection plan for yourself, so that you can get the most credits, and must meet the principle of priority to prerequisites. It is assumed that there is no time conflict between courses.

enter

Line 1: Two integers N and M separated by spaces, where 1≤N≤300 and 1≤M≤N.

Each of the next N rows represents a course. The class numbers are 1, 2, ..., N. Each line has 2 integers separated by spaces. The first number is the course number of the prerequisite course (if there is no prerequisite course, this item is 0), and the second number is the credits of this course. Credits are positive integers not exceeding 10.

Output

Line 1: There is only one number, that is, the total number of credits for the actual selected course.

Tree dp, similar to 01 knapsack problem:

#include<iostream>
#include<iomanip>
#include<vector>
#define N 310
using namespace std;

vector<int>G[N + 1];
vector<vector<int>>dp(N, vector<int>(N, 0));

void dfs(int father, int m)
{
	if (G[father].size() == 0)
		return;
	int son=0;
	for (int i = 0; i < G[father].size(); i++)
	{
		son = G[father][i];
		dfs(son, m);

	for (int i = m + 1; i >=1; i--)
	{
		for (int j = 1; j < i; j++)
			dp[father][i] = max(dp[father][i], dp[son][j] + dp[father][i - j]);
	}

	}
}
void visit()
{
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j <10; j++)
		{
			cout << setw(5)<<dp[i][j];
		}
		cout << endl;
	}

}
int main()
{
	int n, m;
	while (cin >> n >> m)
	{
		for (int i = 1; i <= n; i++)
		{
			int father, score;
			cin >> father >> score;
			G[father].push_back(i);
			dp[i][1] = score;
		}
		visit();

		dfs(0, m);
		cout << dp[0][m + 1] << endl;
		visit();


	}
	return 0;
}
/*
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
*/

 

Guess you like

Origin blog.csdn.net/weixin_40823740/article/details/109400117