hdu1520 http://acm.hdu.edu.cn/showproblem.php?pid=1520
题意是给定一棵树,每个结点有一个价值,要我们选择任意个结点使得总价值最大,规则是如果父亲结点被选了,那么儿子结点不可以被选,但是儿子的儿子可以被选
本来学搜索的时候找到这题搜索题,然后用搜索做的
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 typedef long long LL; 15 const int INF = 1<<30; 16 int val[6666]; 17 int f[6666]; 18 vector<int> g[6666]; 19 int dfs(int u, bool flag)//flag标记父亲结点是不是取 20 { 21 int t,t2; 22 if(!flag) 23 t = val[u]; 24 t2 = 0; 25 for(int i=0; i<g[u].size(); ++i) 26 { 27 int v = g[u][i]; 28 if(!flag) 29 { 30 t += dfs(v,true); 31 } 32 t2 += dfs(v,false); 33 } 34 if(flag) 35 return t2; 36 return max(t,t2); 37 } 38 int main() 39 { 40 int n,i,x,y; 41 while(scanf("%d",&n)!=EOF) 42 { 43 44 for(i=1; i<=n; ++i) 45 { 46 g[i].clear(); 47 scanf("%d",&val[i]); 48 f[i] = -1; 49 } 50 while(scanf("%d%d",&x,&y),x) 51 { 52 g[y].push_back(x); 53 f[x] = y; 54 } 55 x = 1; 56 while(f[x]!=-1) 57 x = f[x]; 58 printf("%d\n",dfs(x,false)); 59 } 60 return 0; 61 }
但是学树形dp的时候又找到这道题,然后用树形dp重新做了一次,提高上去,运行的时间变少了
dp[u][1] 表示选择结点u可以获得的最大价值
dp[u][0]表示不选择结点u可以获得的最大价值
状态转移方程是 dp[u][1] = max( dp[u][1], dp[u][1]+dp[v][0] ); dp[u][0] = max( dp[u][0],max(dp[u][0]+dp[v][1], dp[u][0]+dp[v][0]) );
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 typedef long long LL; 15 const int INF = 1<<30; 16 const int N = 6000 + 10; 17 int val[N]; 18 int dp[N][2];//dp[u][1]表示选这个结点的最大值, dp[u][0] 表示不选这个结点的最大值 19 struct Edge 20 { 21 int v,next; 22 }g[N<<1]; 23 int head[N],e; 24 25 void dfs(int u, int fa) 26 { 27 dp[u][1] = val[u]; 28 dp[u][0] = 0; 29 for(int i=head[u]; i!=-1; i=g[i].next) 30 { 31 int v = g[i].v; 32 if(v==fa) continue; 33 dfs(v,u); 34 dp[u][1] = max(dp[u][1],dp[u][1]+dp[v][0]); 35 dp[u][0] = max(dp[u][0],max(dp[u][0]+dp[v][1],dp[u][0]+dp[v][0] )); 36 37 //dp[u][1] += dp[v][0]; 38 //dp[u][0] += dp[v][1]; 39 } 40 } 41 void init(int n) 42 { 43 for(int i=1; i<=n; ++i) 44 head[i] = -1; 45 e = 0; 46 } 47 void addEdge(int u, int v) 48 { 49 g[e].v = v; 50 g[e].next = head[u]; 51 head[u] = e++; 52 } 53 54 int main() 55 { 56 int n,i,a,b; 57 while(scanf("%d",&n)!=EOF) 58 { 59 init(n); 60 for(i=1; i<=n; ++i) 61 scanf("%d",&val[i]); 62 while(scanf("%d%d",&a,&b),a) 63 { 64 addEdge(a,b); 65 addEdge(b,a); 66 //g[a].push_back(b); 67 //g[b].push_back(a); 68 } 69 dfs(1,-1); 70 printf("%d\n",max(dp[1][0],dp[1][1])); 71 } 72 return 0; 73 }
最近老发现用vector建图提交老师runtime error,
时间: 2024-10-12 12:26:45