经典题了,网上博客一大堆O(nCC)的做法,其实是可以将复杂度降到O(nC)的

参考依赖背包优化(泛化物品的并)

根据背包九讲,求两个泛化物品的和复杂度是O(CC)的,所以依赖背包暴力求解的复杂度是O(nCC)

然后对其进行优化,考虑 F[u][j] 用来表示以结点u为根的子树(不包括u)体积为j的全局最大价值
枚举u的儿子v,求F[v][j]数组,因为要求以v为根的子树,必须先选v,所以把v强行塞到背包里
即通过F[v][j]=F[u][j]+W[v] (j<=C-V[v])这个赋值来表示j子树的最大体积不会超过C-V[v],并且已经选了v
然后dfs求出F[v][j]的值,此时按照定义已经得到了一个新的泛化物品,即一定包含v,并且可能包含v子树元素与前面几棵子树元素的背包,
我们拿这个背包和之前的背包(即一定不包含v的子树)进行合并,去更新F[u],F[u][j]=max(F[u][j],F[v][j-V[v]])
即F[u]在体积为j的时候要么保持原来的值,不取v子树的任何物品,要么取一些v子树的物品,那么显然v物品也要被取

即每次处理完一个u的子树v后,我们就得到了一个和当前泛化物品有交集(或者说是严格的后者包含前者,因为加了一整棵v的子树(除了v没加)进去)的新的泛化背包,我们对其求并,复杂度是O(C),因为对于每个体积,我们只要求两者在该体积下的最大价值即可,当然新的泛化物品因为要强行塞入v,所以最后对应的体积也会偏移V[v]、

加深理解:一整棵子树v是如何逐步加入到决策集合中的。在dfs进入v子树后,会再遍历v的子树w,然后把w强行塞入背包,塞入背包说明前面一定会有一些物品x被挤出必选v的最佳决策集合中,那么回溯的时候我们考虑是选w还是选择x更优,最后回溯到v的时候,整个v的子树已经决策好了。

#include<bits/stdc++.h>
using namespace std;
#define N 205
struct Edge{int to,nxt,w;}e[N<<];
int head[N],tot,n,q;
void init(){memset(head,-,sizeof head);tot=;}
void add(int u,int v,int w){
e[tot].w=w;e[tot].to=v;e[tot].nxt=head[u];head[u]=tot++;
}
int F[N][N];
void dfs(int u,int pre,int C){
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==pre)continue;
for(int j=;j<=C-;j++)
F[v][j]=F[u][j]+e[i].w;
dfs(v,u,C-);
for(int j=;j<=C;j++)
F[u][j]=max(F[u][j],F[v][j-]);
}
} int main(){
while(cin>>n>>q){
init();
for(int i=;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(v,u,w);add(u,v,w);
}
memset(F,,sizeof F);
dfs(,,q);
cout<<F[][q]<<endl;
}
}

这个题要加一个虚根,用暴力显然是过不了的。所以要优化后的依赖背包来做

#include<bits/stdc++.h>
using namespace std;
#define N 65
#define M 32005
#define ll long long
struct Edge{int to,nxt;}e[N<<];
int head[N],tot;
void init(){memset(head,-,sizeof head);tot=;}
void add(int u,int v){
e[tot].to=v;e[tot].nxt=head[u];head[u]=tot++;
} int dp[N][M],V[N],W[N],n,C;
void dfs(int u,int pre,int C){
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==pre)continue;
for(int j=;j<=C-V[v];j++)
dp[v][j]=dp[u][j]+V[v]*W[v];
dfs(v,u,C-V[v]);
for(int j=V[v];j<=C;j++)
dp[u][j]=max(dp[u][j],dp[v][j-V[v]]);
}
} int main(){
while(cin>>C>>n){
init();
for(int i=;i<=n;i++){
int fa;
scanf("%d%d%d",&V[i],&W[i],&fa);
add(i,fa);add(fa,i);//增加一个0结点
}
memset(dp,,sizeof dp);
dfs(,,C);
int ans=;
for(int j=;j<=C;j++)ans=max(ans,dp[][j]);
cout<<ans<<endl;
}
}

依赖背包优化——ural1018,金明的预算方案的更多相关文章

  1. 有依赖的背包---P1064 金明的预算方案

    P1064 金明的预算方案 solution 1 暴搜 70pt dfs (当前搜到了第几个物品,产生的总价值,剩下多少钱) 剪枝 1:如果剩下的钱数<0,直接return就好,没必要继续了 剪 ...

  2. 「NOIP2006」「LuoguP1064」 金明的预算方案(分组背包

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NNN元钱就行” ...

  3. NOIP 2006 金明的预算方案(洛谷P1064,动态规划递推,01背包变形,滚动数组)

    一.题目链接:P1064 金明的预算方案 二.思路 1.一共只有五种情况 @1.不买 @2.只买主件 @3.买主件和附件1(如果不存在附件也要运算,只是这时附件的数据是0,也就是算了对标准的结果也没影 ...

  4. 背包形动态规划 fjutoj2375 金明的预算方案

    金明的预算方案 TimeLimit:1000MS  MemoryLimit:128MB 64-bit integer IO format:%lld   Problem Description 金明今天 ...

  5. tyvj 1057 金明的预算方案 背包dp

    P1057 金明的预算方案 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2006 提高组 第二道 描述 金明今天很开心,家里购置的新房就要领钥匙了 ...

  6. Luogu 1064 金明的预算方案 / CJOJ 1352 [NOIP2006] 金明的预算方案(动态规划)

    Luogu 1064 金明的预算方案 / CJOJ 1352 [NOIP2006] 金明的预算方案(动态规划) Description 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己 ...

  7. NOIP 2006 金明的预算方案

    洛谷 P1064 金明的预算方案 https://www.luogu.org/problem/P1064 JDOJ 1420: [NOIP2006]金明的预算方案 T2 https://neooj.c ...

  8. [codevs1155][KOJ0558][COJ0178][NOIP2006]金明的预算方案

    [codevs1155][KOJ0558][COJ0178][NOIP2006]金明的预算方案 试题描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴 ...

  9. [LuoguP1064][Noip2006]金明的预算方案

    金明的预算方案(Link) 题目描述 现在有\(M\)个物品,每一个物品有一个钱数和重要度,并且有一个\(Q\),如果\(Q = 0\),那么该物件可以单独购买,当\(Q != 0\)时,表示若要购买 ...

  10. 【洛谷P1064】[NOIP2006] 金明的预算方案

    金明的预算方案 显然是个背包问题 把每个主件和它对应的附件放在一组,枚举每一组,有以下几种选法: 1.都不选 2.只选主件 3.一个主件+一个附件 4.一个主件+两个附件 于是就成了01背包.. #i ...

随机推荐

  1. Django过滤器之safe

    safe除了将html生成安全的文本外,还有将整型转为字符串: {% for user in user_list %} {% if user.id|safe == uid %} <li clas ...

  2. vue之全局自定义组件

    在项目开发中,往往需要使用到一些公共组件,比如,弹出消息.面包屑或者其它的组件,为了使用方便,将其以插件的形式融入到vue中,以面包屑插件为例: 1.创建公共组件MyBread.vue <tem ...

  3. Tmux 简单配置使用

    Tmux Prefix (prefix) Tmux 使用 Prefix 以将自身的快捷键与其它应用区分,运行 Tmux 快捷键时首先按下这个 Prefix (默认是 Ctrl-b 组合键),松手后紧接 ...

  4. fiddler增加ip以及响应时间列

    最近打算看一下移动端app的响应等请求,这里打算用fillder来查看appium的模拟出发请求的操作来查看结果, 所以我们需要在左侧的面板增加我们所需要的ip,响应时间等数据以方便我们查看 fidd ...

  5. Jenkins应用

    转自 https://www.cnblogs.com/syw20170419/category/1239520.html Jenkins+Git+Python 进行持续集成接口测试 https://w ...

  6. 【IP】虚拟IP原理

    使用场景: 当这台机器出现故障时,自动动态切换到另一台热备的机器 高可用性HA(High Availability) 指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间 ...

  7. 配置Redis集群为开机自启动

    vim /etc/init.d/redisc 将下方脚本写入redisc文件中 #!/bin/sh # chkconfig: 2345 80 90 # # Simple Redis init.d sc ...

  8. linux python3 venv 虚拟环境报错 [-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 2.

    解决办法: 先创建没有pip的虚拟环境,然后启动虚拟环境后,再安装pip 办法一: 亲测失败了... python3 -m venv --without-pip py36env 办法二 sudo ap ...

  9. AI应用在金融领域,如何能够在商业上有所突破

    AI应用在金融领域,如何能够在商业上有所突破 如今,随着社会不断发展,技术不断进步,国内外各大金融机构已经在大数据.人工智能.区块链等新技术上有很多尝试,智能客服.智能投顾等新金融形式也早已不新鲜.那 ...

  10. Python脚本轻松实现批量图片重命名

    ************************************************************************** 摘要:网上爬取的图片名字很混乱,格式也比较多,需要 ...