树形DP习题

时间:2023-03-09 18:48:24
树形DP习题

听闻noip要考树形DP,本蒟蒻万分惶恐,特刷一坨题目,以慰受惊之心。

codevs 1486

/*和非常出名的“选课”是一个题*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 1010
using namespace std;
int son[N][],f[N][N],v[N],n,m,flag;
int dfs(int x,int y)
{
if(f[x][y]!=-)return f[x][y];
if(x==||y<=)
{
if(!flag)flag=;
else return ;
}
f[x][y]=dfs(son[x][],y);
for(int i=;i<=y-;i++)
f[x][y]=max(f[x][y],dfs(son[x][],i)+dfs(son[x][],y--i)+v[x]);
return f[x][y];
}
int main()
{
memset(f,-,sizeof(f));
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&v[i]);
for(int i=;i<=n;i++)
{
int x,y;scanf("%d%d",&x,&y);
if(!son[x][])son[x][]=y;
else
{
x=son[x][];
while(son[x][])x=son[x][];
son[x][]=y;
}
}
printf("%d",dfs(,m+));
return ;
}

codevs 1163

#include<cstdio>
#include<iostream>
#include<cstring>
#define N 110
using namespace std;
int son[N][],cost[N],val[N],f[N][N*],n,m,p=;
void build(int x)
{
if(val[x])return;
son[x][]=++p;build(p);
son[x][]=++p;build(p);
}
int dfs(int x,int y)
{
if(f[x][y]!=-)return f[x][y];
if(y<=)return ;
if(val[x])return min(val[x],(y/));
int s0=son[x][],s1=son[x][];
f[x][y]=max(dfs(s0,y-cost[s0]),dfs(s1,y-cost[s1]));
for(int i=;i<=y;i++)
f[x][y]=max(f[x][y],dfs(s0,i-cost[s0])+dfs(s1,y-i-cost[s1]));
return f[x][y];
}
int main()
{
memset(f,-,sizeof(f));
scanf("%d",&m);
int x,y;
while(scanf("%d%d",&x,&y)!=EOF)
{
cost[++n]=x*;val[n]=y;
}
build();
printf("%d",dfs(,m-cost[]));
return ;
}

poj 1463

/*
题意:给定一棵树,要求选最少的点,是每条边至少有一个点被选中
f[i][0/1]表示第i个点选或不选的最少花费。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 1510
using namespace std;
int head[N],f[N][],n,cnt;
struct node
{
int v,pre;
};node e[N*];
void add(int x,int y)
{
++cnt;
e[cnt].v=y;
e[cnt].pre=head[x];
head[x]=cnt;
}
void dfs(int x,int fa)
{
f[x][]=;
for(int i=head[x];i;i=e[i].pre)
{
if(e[i].v==fa)continue;
dfs(e[i].v,x);
f[x][]+=min(f[e[i].v][],f[e[i].v][]);
f[x][]+=f[e[i].v][];
}
}
int main()
{
freopen("jh.in","r",stdin);
while(scanf("%d",&n)!=EOF)
{
cnt=;
memset(f,,sizeof(f));
memset(e,,sizeof(e));
memset(head,,sizeof(head));
for(int i=;i<=n;i++)
{
int x,y,z;
scanf("%d:(%d) ",&x,&y);
for(int j=;j<=y;j++)
{
scanf("%d",&z);
add(x,z);add(z,x);
}
}
dfs(,-);
printf("%d\n",min(f[][],f[][]));
}
return ;
}