hdu1011

2024-06-14 19:38
文章标签 hdu1011

本文主要是介绍hdu1011,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

树形dp背包

对任一节点,取得最大值相当于在确定根节点消耗之后对所有子树进行01背包,获得1~m每个状态的最大值,然后向上递归,直至找到根节点,此时求得的最大值即为所求

状态转移方程:dp[i][t]=max(dp[i][t],dp[i][k]+dp[son[i]][t-k])(k=0,1,2......)

#include <iostream>using namespace std;int map[105][105];
int v[105];
int w[105];
int dp[105][105];
int n,m;void build(int s)		//建树,此题比较坑的地方,即给的节点不一定是先父节点后子节点的顺序
{for (int i=1;i<=n;i++){if (map[s][i]==1){map[i][s]=0;build(i);}}
}int max(int a,int b)
{return a>b?a:b;
}void get(int s)
{for (int i=w[s];i<=m;i++)dp[s][i]=v[s];for (int i=1;i<=n;i++){if (map[s][i]==1){get(i);for (int t=m;t>w[s];t--){for (int k=t-1;k>=w[s];k--){dp[s][t]=max(dp[s][t],dp[s][k]+dp[i][t-k]);}}}}   
}int main()
{while (scanf("%d%d",&n,&m)&&n!=-1){memset(map,0,sizeof(map));memset(dp,0,sizeof(dp));for (int i=1;i<=n;i++){scanf("%d%d",&w[i],&v[i]);w[i]=(w[i]+19)/20;}for (int i=1;i<n;i++){int k,t;scanf("%d%d",&k,&t);map[k][t]=map[t][k]=1;}build(1);get(1);if (m==0)cout<<0<<endl;elsecout<<dp[1][m]<<endl;}
}


这篇关于hdu1011的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1061339

相关文章

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

Hdu1011 Starship Troopers -- 树形背包

/*题意:星河战队要去完成任务:用有限的战士去俘获尽可能多的首脑。条件和注意:1:一颗树(没有重边,没有环,没有孤立点),表示敌军的基地地图2:一个战士可以战胜20个敌人,保证战士不重复战斗,不走回路。3:要想抓到首脑,必须要有战士进入房间。分析:树上跑背包。*/#include<iostream>#include<cstring>#include<algorithm>#inc

hdu1011(树形dp)

链接:点击打开链接 题意:有n个节点组成一棵树,有m个士兵,必须从1号房间开始攻打,每个洞防御值1价值b,一个士兵只能产生20的伤害,为了拿到这个节点的价值,必须留下一些士兵消灭这个洞的防御值(并且留下的士兵不可以再去攻打其他节点,并且必须攻打了父节点才可以攻打子节点),问这m个士兵可以得到的最大价值是多少 代码: #include <math.h>#include <vector>#i