程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 2342 樹形DP

poj 2342 樹形DP

編輯:C++入門知識

樹形DP入門題目。

樹形DP說白了就是在搜索的時候動態規劃。

只要你懂的深搜+動態規劃,就能理解這個基礎題了。

先直接搜索到最底層,然後一層一層動態規劃,可以說有點像數塔。

dp[i][1],dp[i][0]代表取這個節點和不取這個節點,所以。

dp[i][1]+=dp[v][0] v是的子節點

dp[i][0]+=max(dp[v][1],dp[v][0])

初始的時候將最後一層葉子節點dp[i][1]賦值為相應值即可。

用鄰接表 似乎更加的直觀,速度自然是更加的快。

#include
#include
#include
using namespace std;
struct node{
	int v,nxt;
}e[12000];
int dp[6005][2],father[6005];
int num,head[6005];

int max(int a,int b){
	return a>b?a:b;
}	
void add(int a,int b){
	e[num].v=b;e[num].nxt=head[a];head[a]=num++;
}		


void dfs(int n){
	int i;
	for(i=head[n];i!=-1;i=e[i].nxt){
		int v=e[i].v;
		if(father[v]==n){
			dfs(v);
			dp[n][1]+=dp[v][0];
			dp[n][0]+=max(dp[v][1],dp[v][0]);
		}
	}	
}	
int main()
{
	int t;
	while(scanf("%d",&t)!=EOF){
		memset(dp,0,sizeof(dp));
		memset(head,-1,sizeof(head));
		memset(father,0,sizeof(father));
		num=0;
		int i;
		for(i=1;i<=t;i++)
			scanf("%d",&dp[i][1]);
		int root=1;
		int a,b;
		while(scanf("%d%d",&a,&b),a||b){
			father[a]=b;
			add(b,a);
			if(father[b]==0) root=b;
		}
		dfs(root);
		printf("%d\n",dp[root][1]>dp[root][0]?dp[root][1]:dp[root][0]);
	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved