Tree DP examples
DP feel a little strange, but this must be strengthened, these kinds of questions it is all too common
First, the topic Link: hdu 1520: Anniversary party
A more classic tree DP entry title. . . .
Array disposed dp
dp [root] [0] indicates that the node is not selected for
dp [root] [1] indicates that the node is selected to
have:
dp[root][0]+=max(dp[son][0],dp[son][1]);
dp[root][1]+=dp[son][0];
Can be divided into three parts
a, achievements, directly in the STL vector can be
two, tree traversal, DFS
three, DP
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
int n;
int dp[6010][5]; //dp[root][1]表示参加宴会,dp[root][0]表示不参加宴会
int value[6010];
int father[6010];
vector<int> tree[6010];
void dfs(int root){
dp[root][0]=0;
dp[root][1]=value[root];
for(int i=0;i<tree[root].size();i++){
int son=tree[root][i];
dfs(son);
dp[root][0]+=max(dp[son][0],dp[son][1]);
dp[root][1]+=dp[son][0];
}
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++){
scanf("%d",&value[i]);
father[i]=-1;
tree[i].clear();
}
int a,b;
while(~scanf("%d%d",&a,&b)){
if(a==0&&b==0)
break;
tree[b].push_back(a);
father[a]=b;
}
int root=1;
//找到根节点
for(int i=1;i<=n;i++){
if(father[i]==-1){
root=i;
}
}
//cout<<root<<endl;
dfs(root);
cout<<max(dp[root][1],dp[root][0])<<endl;
}
return 0;
}
Second, the topic Link: Luo Gu P1040 plus binary tree
In fact, I feel this is a problem, although the tree, but in fact also can be used to solve a range of DP
start really did not expect, even so simple recursive preorder traversal of all cards for a while
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<set>
#include<vector>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
int n;
int flag; //防止最后一个数后面出现空格
ll dp[35][35]; //dp数组
int root[35][35]; //存放根节点
ll search(int l,int r){
ll now; //存放当前根节点所对应的最大加分值
if(l>r)
return 1;
if(dp[l][r]==-1){
for(int k=l;k<=r;k++){
now=search(l,k-1)*search(k+1,r)+dp[k][k];
if(now>dp[l][r]){
dp[l][r]=now;
root[l][r]=k;
}
}
}
return dp[l][r];
}
void preoder(int l,int r){
if(l>r)
return ;
if(flag==0){
flag=1;
}
else{
cout<<' ';
}
cout<<root[l][r];
preoder(l,root[l][r]-1);
preoder(root[l][r]+1,r);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
dp[i][j]=-1;
}
}
for(int i=1;i<=n;i++){
scanf("%lld",&dp[i][i]);
root[i][i]=i;
}
ll ans=search(1,n);
printf("%lld\n",ans);
preoder(1,n);
cout<<endl;
return 0;
}