这道题可以用分组背包来做。

但是分组有两种方式

一种是把主件,主件+附件1,主件+附件2分成一组

组内只能选一个物品

一种是建一颗树,用树形dp的方式去做

第二种更通用,就算物品的依赖关系是森林都可以做

而第一种只限于这道题,因为只有一层关系,所以有特殊解

目前只写了第一种,后面补第二种

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std; const int MAXN = 412;
const int MAXM = 32123;
int f[MAXM], p[MAXN], w[MAXN], fa[MAXN], n, m;
int W[MAXN], P[MAXN], k[MAXN], cnt, N; void add(int w, int p)
{
W[N] = w; P[N] = p; k[N++] = cnt;
} void init()
{
REP(i, 1, n + 1)
if(fa[i] == 0)
{
add(w[i], p[i]);
vector<int> son;
REP(j, 1, n + 1)
if(fa[j] == i)
son.push_back(j);
if(son.size() >= 1) add(w[i] + w[son[0]], p[i] + p[son[0]]);
if(son.size() >= 2)
{
add(w[i] + w[son[1]], p[i] + p[son[1]]);
add(w[i] + w[son[1]] + w[son[0]], p[i] + p[son[1]] + p[son[0]]);
}
cnt++;
}
} int main()
{
scanf("%d%d", &m, &n);
REP(i, 1, n + 1)
{
scanf("%d%d%d", &w[i], &p[i], &fa[i]);
p[i] *= w[i];
}
init();
REP(r, 0, cnt)
for(int j = m; j >= 0; j--)
REP(i, 0, N)
if(k[i] == r && j - W[i] >= 0)
f[j] = max(f[j], f[j - W[i]] + P[i]);
printf("%d\n", f[m]);
return 0;
}

第二种

大家有没有看到这个代码和选课的树形dp的区别。(选课https://blog.csdn.net/qq_34416123/article/details/82258060

这道题是选课的简化版,最多只有两个儿子,而且只有三层。

这份代码多了个递归参数体积。选课那题体积都为1,而cnt数组记录的是以i结尾的子树

的节点的个数,也就是体积。

#include<cstdio>
#include<algorithm>
#include<vector>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
using namespace std; const int MAXN = 112;
const int MAXM = 32123;
int f[MAXN][MAXM], p[MAXN], w[MAXN], n, m;
vector<int> g[MAXN]; void dfs(int u, int k)
{
REP(i, 0, g[u].size())
{
int v = g[u][i];
FOR(j, 0, k - w[v]) f[v][j] = f[u][j];
if(k >= w[v]) dfs(v, k - w[v]);
FOR(j, w[v], k) f[u][j] = max(f[u][j], f[v][j-w[v]] + w[v] * p[v]);
}
} int main()
{
scanf("%d%d", &m, &n);
FOR(i, 1, n)
{
int fa;
scanf("%d%d%d", &w[i], &p[i], &fa);
g[fa].push_back(i);
} dfs(0, m);
printf("%d\n", f[0][m]); return 0;
}

最新文章

  1. 《JS实现复制内容到剪贴板功能,可兼容所有PC浏览器,不兼容手机端》
  2. Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储
  3. 【Openlayers3】在地图上添加highcharts图表
  4. chromium获取代码和编译
  5. Android SQLite总结(一) (转)
  6. 使用git向github中添加项目并更新(备忘录)
  7. Crosswalk入门
  8. python实现发工资脚本
  9. textarea高度自适应问题
  10. 鼠标放上去图片慢慢变大js 或 变大
  11. Selenium 2.0 WebDriver 自动化测试 使用教程 实例教程 API快速参考
  12. HDU 2516 取石子游戏 斐波纳契博弈
  13. 【Scala】Scala之Classes and Properties
  14. 小白的Python之路 day1 变量
  15. 三、checkedListBoxControl
  16. 两个App之间的跳转 并传值
  17. python3.5.2中文字符乱码问题解决
  18. vc++之stdafx.h
  19. js变量作用域--变量提升
  20. UITabBarController支持旋转

热门文章

  1. 2、Attentive Group Recommendation----注意力集中的群组推荐
  2. DOM元素属性值如果设置为对象
  3. 51nod 1302(贪心+平衡树)
  4. Vue 实现前进刷新,后退不刷新的效果
  5. Spring中的InitializingBean接口
  6. 【Codeforces Round #482 (Div. 2) C】Kuro and Walking Route
  7. 【codeforces 794C】Naming Company
  8. android 使用讯飞人脸识别api报错:java.lang.UnsatisfiedLinkError
  9. 查看系统的I/O使用iostat命令而使用iotop能够依据I/O统计信息排序,追踪到详细的进程
  10. 构建自己的AngularJS - 作用域和Digest(三)