P2014 [CTSC1997] Course selection (dependent tree dp)

P2014 [CTSC1997] Course Selection

Topic description
Every student in the university, in order to achieve a certain credit, must choose some courses from many courses to study. In the course, some courses must be studied before certain courses. For example, advanced mathematics is always studied before other courses. Now there are N courses, each course has one credit, each course has one or no direct prerequisites (if course a is a prerequisite course of course b, that is, course b can only be studied after course a). A student chooses M courses from these courses, and asks what is the highest degree he can get?

Input format The
first line has two integers N, M separated by spaces. (1≤N≤300, 1≤M≤300) The
next N rows, the I+1 row contains two integers k_i and s_i, k_i represents the direct prerequisite course of the first course, and s_i represents the first course Of credits. If k_i=0, it means that 1≤k_i≤N and 1≤s_i≤20 are not directly repaired.

The output format is
only one line, choose the maximum score of M courses.

Input and output sample
input

7  4
2  2
0  1
0  4
2  1
7  1
7  6
2  2

Output

13

Idea: This
question is actually an upgraded version of the binary apple tree , the only difference is that it is a polytree, and the binary apple tree is a binary tree. Then how can we do interval dp on the tree like the previous question? In fact, can also be seen as a multi-tree binary tree, the tree almost finished searching the sub-unified as the left subtree, to connect to the search as a separate sub-tree that right subtree, as shown below:
Insert picture description here
then and II Like fork apple tree

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=3e2+10;
int n,m,k,v,way[N][N],son[N][N],f[N][N];
int vis[N];
void dfs(int root)
{
    
    
	vis[root]=1;
	for(int i=1;i<=son[root][0];i++)
	{
    
    
		int v=son[root][i];
		if(!vis[v])
		{
    
    
			dfs(v);
			for(int j=m;j>=0;j--)
			for(int k=j-1;k>=0;k--)
			f[root][j]=max(f[root][j],f[root][j-k-1]+f[v][k]+way[root][v]);	
		}
	}
}
int main()
{
    
    
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
    
    
		scanf("%d%d",&k,&v);
		way[k][i]=v;
		son[k][++son[k][0]]=i;
	}
	dfs(0);
	printf("%d",f[0][m]);
	return 0;
} 

Guess you like

Origin blog.csdn.net/bigwinner888/article/details/108023258