poj2486
2015-07-20 10:21
344 查看
一颗树,n个点,每个点上有一个权值,
求从1出发,最多走k步,遍历到的点的最大权值和
(每个点权对权值和最多只能贡献一次)
(1 <= n <= 100, 0 <= k <= 200)
f(i,j,k)f(i, j, k) 在 ii 的子树内走 jj 步回到 ii 点(k=0)(k=0)/不回到 ii 点(k=1)(k=1)的最大收益
然后DPDP即可,时间复杂度 O(n∗k2)O(n*k^2)
状态转移方程:
dp(i,j,0)=dp(i,j−k,0)+dp(son,k−2,0)dp(i, j, 0) = dp(i, j-k, 0)+dp(son, k-2, 0)
dp(i,j,1)=dp(i,j−k,1)+dp(son,k−2,0)dp(i, j, 1) = dp(i, j-k, 1)+dp(son, k-2, 0)
dp(i,j,1)=dp(i,j−k,0)+dp(son,k−1,1)dp(i, j, 1) = dp(i, j-k, 0)+dp(son, k-1, 1)
求从1出发,最多走k步,遍历到的点的最大权值和
(每个点权对权值和最多只能贡献一次)
(1 <= n <= 100, 0 <= k <= 200)
f(i,j,k)f(i, j, k) 在 ii 的子树内走 jj 步回到 ii 点(k=0)(k=0)/不回到 ii 点(k=1)(k=1)的最大收益
然后DPDP即可,时间复杂度 O(n∗k2)O(n*k^2)
状态转移方程:
dp(i,j,0)=dp(i,j−k,0)+dp(son,k−2,0)dp(i, j, 0) = dp(i, j-k, 0)+dp(son, k-2, 0)
dp(i,j,1)=dp(i,j−k,1)+dp(son,k−2,0)dp(i, j, 1) = dp(i, j-k, 1)+dp(son, k-2, 0)
dp(i,j,1)=dp(i,j−k,0)+dp(son,k−1,1)dp(i, j, 1) = dp(i, j-k, 0)+dp(son, k-1, 1)
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <string> #include <map> #include <vector> #include <stack> #include <queue> #include <utility> #include <iostream> #include <algorithm> const int maxn = 105, maxk = 205; int n, m, k, w[maxn]; std::vector<int> edge[maxn]; int dp[maxn][maxk][2], ans; #define update(dest,x) dest = std::max(dest, x) #define VecErase(x) x.erase(x.begin(),x.end()) void clear() { memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) VecErase(edge[i]); ans = 0; } #undef VecErase void dfs(int a,int fa) { for(int i = 0, p; i < edge[a].size(); i++) if((p = edge[a][i]) != fa) { dfs(p, a); for(int j = k; j >= 1; j--) { update(dp[a][j][1], dp[a][j-1][0] + dp[p][0][1]); for(int t = 2; t <= j; t++) { update(dp[a][j][0], dp[a][j-t][0] + dp[p][t-2][0]); update(dp[a][j][1], dp[a][j-t][0] + dp[p][t-1][1]); update(dp[a][j][1], dp[a][j-t][1] + dp[p][t-2][0]); } } } } int main() { #ifndef ONLINE_JUDGE freopen("poj2486.in","r",stdin); freopen("poj2486.out","w",stdout); #endif while(std::cin >> n) { clear(), std::cin >> k; for(int i = 1; i <= n; i++) { std::cin >> w[i]; for(int j = 0; j <= k; j++) for(int t = 0; t < 2; t++) dp[i][j][t] = w[i]; } for(int i = 1, u, v; i < n; i++) { std::cin >> u >> v; edge[u].push_back(v); edge[v].push_back(u); } dfs(1, 0); ans = std::max(dp[1][k][0], dp[1][k][1]); std::cout << ans << std::endl; } #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
相关文章推荐
- error C2440: '=' : cannot convert from 'void *' to 'mat **'怎么回事阿
- poj2486 分类: poj 2015-07-20 10:21 12人阅读 评论(0) 收藏
- 初试 Coding.net 在线IDE――WebIDE
- 浅谈微端游戏设计思路
- 为方便广大基友查询基站,minigps 开发了android版免费查询基站app
- App调试内存泄露之Context篇(上)
- ACM练习流程
- 进程
- iOS按钮显示的字体模糊的问题
- LinQ和ADO.Net增删改查 备忘
- [spark]Spark Streaming教程
- Java模拟QQ桌面截图功能实现方法
- 怪异模式(Quirks Mode)对 HTML 页面的影响
- 网络流(最大流和最小费用流)
- .hpp的相关的使用规则
- JAVA数据类型转换
- FreeMarker 属性不能为空
- C#.NET SQL数据库备份与还原解决方案
- 6月国内网民地域分布TOP12:湖南湖北排名互换
- SoundCloud 的开发功能