vijos p1642(树形dp优化)
2016-09-29 21:09
274 查看
链接:点击打开链接
题意:有一个含有n个节点的树,给出每个节点的权值,对于每个节点来说,只有选择当前节点的父节点才能选择当前节点,问选择不超过m个节点的最大权值和
代码1:
代码2:
论文地址:《浅谈数据的合理组织》
题意:有一个含有n个节点的树,给出每个节点的权值,对于每个节点来说,只有选择当前节点的父节点才能选择当前节点,问选择不超过m个节点的最大权值和
代码1:
#include <vector> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const long long INF=0x3f3f3f3f3f3f3f3f; long long n,m; vector<long long> G[1005]; long long num[1005],dp[1005][1005]; void dfs1(long long s){ long long i,tmp; for(i=0;i<G[s].size();i++){ tmp=G[s][i]; dfs1(tmp); num[s]+=num[tmp]; } } void dfs2(long long s){ //dp[i][j]表示到第i个节点选了j个节点 long long i,j,k,tmp; for(i=0;i<G[s].size();i++){ tmp=G[s][i]; dfs2(tmp); for(j=min(num[s],m);j>=1;j--){ for(k=1;k<j;k++) dp[s][j]=max(dp[s][j],dp[s][j-k]+dp[tmp][k]); } } } int main(){ //预先处理出节点数进行常数优化 long long i,j,x,ans,sum; //可以水过去,实际复杂度O(n*n*m) while(scanf("%I64d%I64d",&n,&m)!=EOF){ for(i=1;i<=n;i++){ G[i].clear(); num[i]=1,dp[i][0]=0; for(j=1;j<=n;j++) dp[i][j]=-INF; } for(i=1;i<=n;i++){ scanf("%I64d%I64d",&dp[i][1],&sum); while(sum--){ scanf("%I64d",&x); G[i].push_back(x); } } dfs1(1); //先处理出子节点个数 dfs2(1); ans=0; for(i=0;i<=m;i++) //注意可以不用选m个 ans=max(ans,dp[1][i]); printf("%I64d\n",ans); } return 0; }
代码2:
#include <vector> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const long long INF=0x3f3f3f3f3f3f3f3f; long long n,m; vector<long long> lis,G[1005]; long long num[1005]; long long val[1005],dp[1005][1005]; void dfs(int s){ int i,tmp; lis.push_back(s); for(i=0;i<G[s].size();i++){ tmp=G[s][i]; dfs(tmp); num[s]+=num[tmp]; } } int main(){ //通过处理出前序遍历的顺序,和通过 long long i,j,x,ans,sum; //同层节点和同层子树的转移,将复杂 while(scanf("%I64d%I64d",&n,&m)!=EOF){ //度将为O(nm) lis.clear(); //主要在于<<浅谈数据的合理组织>>这篇论文论文和 lis.push_back(0); //自己分析转移的过程来理解 for(i=1;i<=n;i++){ G[i].clear(); for(j=0;j<=n;j++) dp[i][j]=0; } for(i=1;i<=n;i++){ num[i]=1; scanf("%I64d%I64d",&val[i],&sum); while(sum--){ scanf("%I64d",&x); G[i].push_back(x); } } dfs(1); for(i=1;i<=n;i++) dp[i][1]=val[lis[i]]; for(i=n-1;i>=0;i--) for(j=1;j<=m;j++) dp[i][j]=max(dp[i+1][j-1]+val[lis[i]],dp[i+num[lis[i]]][j]); ans=0; for(i=0;i<=m;i++) ans=max(ans,dp[1][i]); printf("%d\n",ans); } return 0; }
论文地址:《浅谈数据的合理组织》
相关文章推荐
- 树形背包DP的两种优化方式——vijos1676、codeforces815c
- 树形DP的一些优化
- bzoj 2645: Vijos1676 陶陶吃苹果 (树形DP)
- dp优化专辑 J -Maximize Game Time [树形dp]
- Vijos P_1002 过河 状态优化dp
- Vijos 1144 小胖守皇宫 【树形DP】
- vijos1037 搭建双塔-状态优化dp
- 最大疯子树:树形DP优化:二次扫描+换根法(poj3585)
- 【vijos1144】小胖守皇宫(树形DP)
- Vijos 1144 小胖守皇宫 【树形DP】
- label {树形dp+机智的优化}
- VIJOS-P1144 小胖守皇宫(树形dp)
- dp优化专辑 I - Cut the Tree [树形dp]
- [vijos1892]树上的最大匹配(树形DP)
- Vijos 1144 小胖守皇宫 [树形dp]
- 【vijos1243】【单调队列优化DP】生产产品
- 【vijos】【树形dp】佳佳的魔法药水
- [vijos1476]旅游规划(csapc)(树形dp)
- Vijos 1180 选课 [树形dp]
- HDU - 5909 Tree Cutting 树形DP+fwt优化 或点分治(待补)