首页 > 代码库 > 树形DP习题
树形DP习题
听闻noip要考树形DP,本蒟蒻万分惶恐,特刷一坨题目,以慰受惊之心。
codevs 1486
/*和非常出名的“选课”是一个题*/ #include<cstdio> #include<iostream> #include<cstring> #define N 1010 using namespace std; int son[N][2],f[N][N],v[N],n,m,flag; int dfs(int x,int y) { if(f[x][y]!=-1)return f[x][y]; if(x==0||y<=0) { if(!flag)flag=1; else return 0; } f[x][y]=dfs(son[x][1],y); for(int i=0;i<=y-1;i++) f[x][y]=max(f[x][y],dfs(son[x][0],i)+dfs(son[x][1],y-1-i)+v[x]); return f[x][y]; } int main() { memset(f,-1,sizeof(f)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&v[i]); for(int i=1;i<=n;i++) { int x,y;scanf("%d%d",&x,&y); if(!son[x][0])son[x][0]=y; else { x=son[x][0]; while(son[x][1])x=son[x][1]; son[x][1]=y; } } printf("%d",dfs(0,m+1)); return 0; }
codevs 1163
#include<cstdio> #include<iostream> #include<cstring> #define N 110 using namespace std; int son[N][2],cost[N],val[N],f[N][N*6],n,m,p=1; void build(int x) { if(val[x])return; son[x][0]=++p;build(p); son[x][1]=++p;build(p); } int dfs(int x,int y) { if(f[x][y]!=-1)return f[x][y]; if(y<=0)return 0; if(val[x])return min(val[x],(y/5)); int s0=son[x][0],s1=son[x][1]; f[x][y]=max(dfs(s0,y-cost[s0]),dfs(s1,y-cost[s1])); for(int i=0;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,-1,sizeof(f)); scanf("%d",&m); int x,y; while(scanf("%d%d",&x,&y)!=EOF) { cost[++n]=x*2;val[n]=y; } build(1); printf("%d",dfs(1,m-cost[1])); return 0; }
poj 1463
/* 题意:给定一棵树,要求选最少的点,是每条边至少有一个点被选中 f[i][0/1]表示第i个点选或不选的最少花费。 */ #include<cstdio> #include<iostream> #include<cstring> #define N 1510 using namespace std; int head[N],f[N][2],n,cnt; struct node { int v,pre; };node e[N*2]; 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][1]=1; for(int i=head[x];i;i=e[i].pre) { if(e[i].v==fa)continue; dfs(e[i].v,x); f[x][1]+=min(f[e[i].v][0],f[e[i].v][1]); f[x][0]+=f[e[i].v][1]; } } int main() { freopen("jh.in","r",stdin); while(scanf("%d",&n)!=EOF) { cnt=0; memset(f,0,sizeof(f)); memset(e,0,sizeof(e)); memset(head,0,sizeof(head)); for(int i=1;i<=n;i++) { int x,y,z; scanf("%d:(%d) ",&x,&y); for(int j=1;j<=y;j++) { scanf("%d",&z); add(x,z);add(z,x); } } dfs(0,-1); printf("%d\n",min(f[0][0],f[0][1])); } return 0; }
树形DP习题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。