HDU 4169 UVALive 5741 Wealthy Family
树形背包。DP递推的思路很简单....
但是由于节点有15万个,先不论空间复杂度,这样开dp数组 dp[150000+10][300+10],如果初始化是memset(dp,-1,sizeof dp),则必然超时。
所以需要一个状态数剪枝。。。即记录这个节点最多组合的数量。
UVALive是不限制内存的,所以dp[150000+10][300+10] 能够AC,HDU 4169 限制了内存大小,需要优化空间复杂度。
内存优化之后的代码,HDU上C++能AC,G++依旧MLE。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std; const int maxn=+;
struct Node
{
int val;
int fa;
queue<int *>Q;
vector<int>f;
}node[maxn];
int n,k,root;
int cnt[maxn];
int ans; void init()
{
memset(cnt,,sizeof cnt);
for(int i=;i<=n;i++)
{
while(!node[i].Q.empty()) node[i].Q.pop();
node[i].f.clear();
}
} void read()
{
for(int i=;i<=n;i++)
{
scanf("%d%d",&node[i].fa,&node[i].val);
if(!node[i].fa) root=i;
else node[node[i].fa].f.push_back(i);
}
} void dfs(int now)
{
if(!node[now].f.size())
{
cnt[now]=;
int *p=new int[cnt[now]+];
p[]=; p[]=node[now].val;
node[node[now].fa].Q.push(p);
delete[] p;
return;
} for(int i=;i<node[now].f.size();i++)
{
int id=node[now].f[i];
cnt[now]=cnt[now]+cnt[id];
} cnt[now]=min(k,cnt[now]); int *p=new int[cnt[now]+]; p[]=;
for(int i=;i<=cnt[now];i++) p[i]=-; int id=;
while(!node[now].Q.empty())
{
int *head=node[now].Q.front();
node[now].Q.pop(); for(int j=cnt[now];j>=;j--)
for(int s=;s<=j&&s<=cnt[node[now].f[id]];s++)
if(head[s]!=-&&p[j-s]!=-)
p[j]=max(p[j],head[s]+p[j-s]);
id++;
}
p[]=max(p[],node[now].val); node[node[now].fa].Q.push(p); if(now==)
{
if(cnt[]<k||p[k]==-) ans=-;
else ans=p[k];
} delete[] p;
return;
} void work()
{
dfs(root);
if(ans==-) printf("impossible\n");
else printf("%d\n",ans);
} int main()
{
while(~scanf("%d%d",&n,&k))
{
init();
read();
work();
}
return ;
}
二维DP写法。HDU 上MLE的。UvaLive能过的。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; int n, k;
int root;
const int maxn = + ;
struct Edge
{
int now;
int next;
}e[maxn];
int head[maxn];
int cnt[maxn];
int val[maxn];
int dp[maxn][ + ];
int q; void init()
{
q=;
for(int i=;i<=n;i++) head[i]=-;
} void read()
{
for (int i = ; i <= n; i++)
{
int fa;
scanf("%d%d", &fa, &val[i]);
if (!fa) root = i;
else
{
e[q].now=i, e[q].next=head[fa];
head[fa]=q, q=q+;
}
}
} void dfs(int now)
{
cnt[now]=;
if (head[now]==-)
{
cnt[now]=;
dp[now][] = val[now];
return;
} for (int i = head[now]; i!=-; i=e[i].next)
{
int id = e[i].now;
dfs(id);
cnt[now]=cnt[now]+cnt[id];
} cnt[now]=min(cnt[now],k); for(int i=;i<=cnt[now];i++) dp[now][i]=-;
dp[now][]=; for (int i = head[now]; i!=-; i=e[i].next)
{
int id = e[i].now;
for(int j=cnt[now];j>=;j--)
for(int s=;s<=j&&s<=cnt[id];s++)
if(dp[id][s]!=-&&dp[now][j-s]!=-)
dp[now][j]=max(dp[now][j],dp[id][s]+dp[now][j-s]);
}
dp[now][]=max(val[now],dp[now][]);
} void work()
{
dfs(root);
if (cnt[root]<k||dp[root][k] == -) printf("impossible\n");
else printf("%d\n", dp[root][k]);
} int main()
{
while (~scanf("%d%d", &n, &k))
{
init();
read();
work();
}
return ;
}
HDU 4169 UVALive 5741 Wealthy Family的更多相关文章
- HDU 4169 Wealthy Family(树形DP)
Problem Description While studying the history of royal families, you want to know how wealthy each ...
- HDU 4169 树形DP
Wealthy Family Problem Description While studying the history of royal families, you want to know ho ...
- hdu 4169 二分匹配最大独立集 ***
题意:有水平N张牌,竖直M张牌,同一方向的牌不会相交.水平的和垂直的可能会相交,求最少踢出去几张牌使剩下的牌都不相交. 二分匹配 最小点覆盖=最大匹配. 链接:点我 坐标点作为匹配的端点 #inclu ...
- HDU 5741 Helter Skelter(构造法)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5741 [题目大意] 一个01相间的串,以0开头,给出的序列每个数字表示连续的0的个数或者1的个数, ...
- POJ 3342 Party at Hali-Bula / HDU 2412 Party at Hali-Bula / UVAlive 3794 Party at Hali-Bula / UVA 1220 Party at Hali-Bula(树型动态规划)
POJ 3342 Party at Hali-Bula / HDU 2412 Party at Hali-Bula / UVAlive 3794 Party at Hali-Bula / UVA 12 ...
- POJ 1087 A Plug for UNIX / HDU 1526 A Plug for UNIX / ZOJ 1157 A Plug for UNIX / UVA 753 A Plug for UNIX / UVAlive 5418 A Plug for UNIX / SCU 1671 A Plug for UNIX (网络流)
POJ 1087 A Plug for UNIX / HDU 1526 A Plug for UNIX / ZOJ 1157 A Plug for UNIX / UVA 753 A Plug for ...
- POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / SCU 1132 Invitation Cards / ZOJ 2008 Invitation Cards / HDU 1535 (图论,最短路径)
POJ 1511 Invitation Cards / UVA 721 Invitation Cards / SPOJ Invitation / UVAlive Invitation Cards / ...
- UVALive - 4223(hdu 2926)
---恢复内容开始--- 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962 Trucking Time Limit: 20000/10000 MS ...
- HDU 5741 Helter Skelter
离线处理+扫描线.题意很容易转化:若干个矩形形成并集,询问一些点是否在并集中? 官方题解不是这样做的....那种做法效率更高,暂时还不会.我这样是4500ms G++过的,C++TLE...... 区 ...
随机推荐
- JUST SORT
We define B is a Divisor of one number A if A is divisible by B. So, the divisors of 12 are 1, 2, 3, ...
- tiny210移植linux内核(3.0.8)杂项
关于三星芯片nand内存分区文件: linux-3.0.8/drivers/mtd/nand/s3c_nand.c struct mtd_partition s3c_partition_info[] ...
- ubuntu 常用命令记录
1.# 表示权限用户(如:root),$ 表示普通用户 开机提示:Login:输入用户名 password:输入口令 用户是系统注册用户成功登陆后,可以进入相应的用户环境. 退出当前shel ...
- js 基础对象二
大的分类 JavaScript 对象 JS Array JS Boolean JS Date JS Math JS Number JS String JS RegExp JS Functions JS ...
- android性能优化优秀文章
郭霖最近整理的文章: 合理管理内存 分析编码过程中如何避免过多内存占用,以及如何实现高性能的内存使用. 尽可能使用intentService; 当界面不可见时释放内存; 当内存紧张时释放内存; 避免b ...
- IP地址、子网掩码详解
如何通过子网掩码划分网段 资料一: 一.缺省A.B.C类地址,子网掩码: 二.子网掩码的作用: code: IP地址 192.20.15.5 11000000 00010100 00001111 ...
- 【摘自网络】dll库和lib库有什么区别
简单地讲:第一:.DLL是动态链接库,而.LIB是静态链接库dll是个编译好的程序,调用时可以直接调用其中的函数,不参加工程的编译. 而lib应该说是一个程序集, 只是把一些相应的函数总结在一起, 如 ...
- cs的变态语法
int? a = null; //?指示a为可空checked { ... } //赋值溢出抛异常unchecked { ... } //赋值溢出不抛异常expr1??expr2 //空结合运算符,e ...
- Android中监听webview监听是否加载完成
之前写过一篇捕获Phoengap的webview事件的方法,主要是在实现了CordovaInterface的Activity中, 在onMessage中根据第一个参数的message name来判断 ...
- HDU-5289<two pointers>
题意: 求一个数列中存在多少个区间,每个区间内的数的差不超过k; 思路:two_pointers; #include<iostream> #include<cstdio> #i ...