HDU
来源:互联网 发布:淘宝卖家销量排行榜 编辑:程序博客网 时间:2024/06/11 20:05
HDU - 4044传送门
题意:给一棵树,树根一定是1,敌人在1位置,每个叶子节点是你的基地,每个节点(包括1节点和你的基地)可以建一个防御塔,每个节点有多种防御塔供你选择,告诉你每种防御塔的价钱和防御能力。你现在有m这么多钱,你可以所有节点上建塔,每个节点只能建一个或不建塔。敌人很聪明,它会去摧毁防御最弱的路线(路线上所有点的防御能力之和)的基地。问你防御最弱的路线防御能力的最大值可以是多少?
思路:树形DP,从根节点开始状态转移,对于节点x,先同过分组背包计算出当前用费应j所得到的最大伤害(要求儿子节点中最小伤害那一个),用01背包加上在x点放置炮台,所得到的费用j的最大伤害。
注意:当一个炮台的费用为0时,不能用简单的背包解决,要加一个tem,具体看代码。
#include<cstdio>#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<map>#include<cstring>using namespace std;const int INF=0x3f3f3f3f;const int N=6100;bool vis[N];int n,m,dp[N][1033];vector<int> a[1055],b[1055],g[N];void dfs(int x){ vis[x]=true; dp[x][0]=INF; //后面求所有子节点最小值时,当放置第一个炮台,利用min得到第一个节点炮台的值,第二个节点会被自动清零(如果有的话) for(int i=0;i<g[x].size();i++) { int y=g[x][i]; if(vis[y])continue; dfs(y); for(int v=m;v>=0;v--) { int tem=0; for(int j=0;j<=v;j++) tem=max(tem,min(dp[x][v-j],dp[y][j])); dp[x][v]=tem; } } if(dp[x][0]==INF)dp[x][0]=0; for(int v=m;v>=0;v--) { int tem=dp[x][v]; for(int i=0;i<a[x].size();i++) if(v>=a[x][i]) tem=max(tem,dp[x][v-a[x][i]]+b[x][i]);//如果炮台造价为0,则dp[x][v]的值不但在变,会得到错误的答案 dp[x][v]=tem; }}int main(){ int ta,x,y,z; scanf("%d",&ta); while(ta--) { scanf("%d",&n); for(int i=1;i<=n;i++) g[i].clear(); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } scanf("%d",&m); for(int i=1;i<=n;i++) { a[i].clear(); b[i].clear(); scanf("%d",&x); while(x--) { scanf("%d%d",&y,&z); a[i].push_back(y); b[i].push_back(z); } } memset(vis,false,sizeof(vis)); memset(dp,0,sizeof(dp)); dfs(1); int ans=dp[1][m]; printf("%d\n",ans); } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- 运算符重载
- c语言fread函数的总结
- 【C#学习】.NET类库中的继承
- Maven 插件之 docker-maven-plugin 的使用
- centos6.5 MailScanner+ Spamassassin垃圾邮件过滤器+clamav 杀毒软件
- HDU
- [Python] wxPython 菜单栏控件学习总结(原创)
- JPush极光推送Java服务器端实例
- 等待唤醒机制
- 很久之前写的日历
- vs2015 常用快捷键整理
- Linux下freeradius-server和freeradius-client的安装和验证
- 文本内容超出后显示省略号效果
- git