The more, The Better(HDU-1561)
Problem Description
ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗?
Input
每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。
Output
对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。
Sample Input
3 2
0 1
0 2
0 3
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
0 0Sample Output
5
13
思路:树形 DP
设 dp[i][j] 为以第 i 号为根取 j 个的最大值,显然,当以 i 号结点为根取 1 个时,其值为第 i 号城堡本省的价值,即 dp[i][1]=w[i]
以样例 2 为例,可以建得如下的一个图
选择一棵树,从根节点向子节点直接进行动态规划,由于对任意结点 i 有 dp[i][1]=w[i],那么如果要求 dp[i][j] 的话,就要对其子树达到最优后再解决当前的问题,即有:dp[i][j]=max{ dp[i][j],dp[i][k]+dp[子节点][i-k] },其中 k 代表取k个点
得到状态转移方程后,可以发现,图是一个森林,这个时候,就需要加一个虚拟的根节点,将其权值设为 0,从其开始进行状态转移,这样一来,就要求包括其自身在内的 m+1 个点的最优值
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define PI acos(-1.0)
#define E 1e-6
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define N 1001
#define LL long long
using namespace std;
struct Edge{int next;int to;
}edge[N];
int head[N],cnt;
int n,m;
int dp[N][N];//以i为根攻破j个城堡的最大值
bool vis[N];
void addEdge(int next,int to){edge[cnt].to=to;edge[cnt].next=head[next];head[next]=cnt++;
}
int dfs(int x){//以x为根结点向下搜索vis[x]=true;for(int i=head[x];i!=-1;i=edge[i].next){int y=edge[i].to;//与x邻接的点if(!vis[y])dfs(y);for(int j=m+1;j>=2;j--)//除虚拟的根结点外,枚举要攻破的城堡个数for(int k=1;k<j;k++)//取k个点if(dp[y][j-k]!=-1&&dp[x][k]!=-1)dp[x][j]=max(dp[x][j],dp[x][k]+dp[y][j-k]);}
}
int main(){while(scanf("%d%d",&n,&m)!=EOF&&(n+m)){memset(dp,-1,sizeof(dp));memset(head,-1,sizeof((head)));memset(vis,false,sizeof(vis));cnt=0;//由于图可能为一森林,因此加一虚拟根节点,使其值为0for(int i=0;i<=n;i++)dp[i][0]=0;dp[0][1]=0;for(int i=1;i<=n;i++){int x,y;scanf("%d%d",&x,&y);addEdge(x,i);dp[i][1]=y;//以第i个点为根攻破1的城堡的值一定是这个城堡自身的值}dfs(0);//以虚拟结点为根节点向下搜索printf("%d\n",dp[0][m+1]);}return 0;
}
The more, The Better(HDU-1561)相关推荐
- 有源汇有上下界最大流/最小流 配题(HDU 3157)
因为是有源汇所以设源点为 s,汇点为 t. 有源汇有上下界最大流: 连接一条 t 指向 s 的边,容量为 INF. 通过上述步骤,现在图变成了无源汇网络. 引入超级源点 S,超级汇点 T. 连接一条 ...
- 最大表示法--环形字符串最大字典序(HDU 5442)
http://acm.hdu.edu.cn/showproblem.php?pid=5442 问题概述:n个字符围成一个环,请从这个环中找出字典序最大的长度为n的字符串,输出它的起始点和方向(0顺1 ...
- HDU2019多校第二场 1009(HDU 6599) I Love Palindrome String(回文树(自动机)+manacher)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6599 解题思路: 回文自动机求每个本质不同的子串出现的次数,同时记录每个节点i代表的回文串第一次出现的 ...
- S-Nim (HDU 1536)组合博弈SG多组游戏
S-Nim 题目链接 Problem Description Arthur and his sister Caroll have been playing a game called Nim for ...
- BestCoder25 1001.Harry and Magical Computer(hdu 5154) 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5154 题目意思:有 n 门 processes(编号依次为1,2,...,n),然后给出 m 种关系: ...
- (HDU - 1847)Good Luck in CET-4 Everybody!(博弈)
题目链接:Good Luck in CET-4 Everybody! - HDU 1847 - Virtual Judge (ppsucxtt.cn) 题目是中文的,我在这就不翻译题意了. 先说一种打 ...
- 美素数(HDU 4548)(打表,简化时间复杂度)
相信大家都喜欢美的东西,让我们一起来看看美素数吧. 问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为"美素数",如29,本身是素数,而且2+9 = 11 ...
- 单词数(HDU 2072)
lily的好朋友xiaoou333最近很空,他想了一件没有什么意义的事情,就是统计一篇文章里不同单词的总数.下面你的任务是帮助xiaoou333解决这个问题. Input 有多组数据,每组一行,每组就 ...
- Ant Trip(HDU 3018)---多笔画问题
题目链接 题目描述 Ant Country consist of N towns.There are M roads connecting the towns. Ant Tony,together w ...
- 机器人的舞蹈(hdu 2232)
机器人的舞蹈 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
最新文章
- Python设计模式-外观模式
- 美国德州光伏装机可能拉低当地峰值电价
- linux c 文件操作
- C语言函数指针 和 OC-Block
- 初学PX4之飞控算法
- [前台]---关于input标签的value值
- java 执行顺序混乱_java类执行顺序问题
- 在内存中创建临时表和表变量
- 【文献学习】强化学习3:基于数据的方法
- mysql one database_数据库中schema和database有什么区别?
- 天翼云高可用虚拟IP(HAVIP)实践
- java生成小程序二维码
- 申领电子驾照提示证件照不标准
- Mac系统怎样设置开机启动项
- python的turtle模块制作的打地鼠小游戏2019/4/9版
- 【压缩感知合集7】压缩感知RIP有限等距性:定义解析,理解说明,数学原理推导
- 华为5g鸿蒙系统手机多少钱,华为Mate30Pro或成今年机皇:鸿蒙系统+麒麟985+5G基带,价格感人...
- Mysql.数据备份
- php购物商城,基于PHP的网上商城
- php 二维码白边,php生成缩略图自动填充白边例子