最近两天做了几题简单的树状DP,觉得简单树状DP只是应用了递归的思想,着重于把每个点作为根结点来思考。。。在对于某个点,可能要对其子树进行01背包或者组合什么的,然后得到这个点的什么信息,这样不断递归(往根结点递归,有时也会双向的)就推到根结点了。。。下面是做过的几题:
RQNOJ6 金明的预算 小明想买一些物品,而每个物品要么是主件,要么是附件(买附件一定得买主件),买了某件物品会得到一个happy值,求给一定的钱最大的happy值?
这题是背包九讲的第七讲,通过这后面还提到泛化物品的概念,根据附属关系,然后建树,f[i][j]表示以i为根结点(i必须买),在子树中花j钱获得的最大快乐值。hdu1561是一样的,下面是喵呜那题的核心代码。
void DFS(int t) { int i,j,k; dp[t][1]=a[t]; for (i=0;i<edge[t].size();i++) { DFS(edge[t][i]); for (j=m+1;j>0;j--) { for (k=1;k<=j;k++) { dp[t][j]=Max(dp[t][j],dp[t][k]+dp[edge[t][i]][j-k]); } } } } 转自http://blog.csdn.net/magicnumber/archive/2011/03/28/6284078.aspx
pku3345 Bribing FIPA 选票,花一代价买通一个人可获得它及它所有后代的支持,求至少获得m个人支持所需最少代价?
f[i][j]表示以i为根的树,获得j人支持所需的最少代价。跟上题很相似。
pku3342 Party at Hali-Bula 求无直属上司(不会有环)最多有多少人能同时出席一个晚会?根据直属关系建树,然后f[i][0]表示i不出席晚会其子树中最多的出席人数,f[i][1]表示i出席晚会以其为根的树中最多的出席人数。结果就是max(f[0][0],f[0][1]).
pku1848 Tree 对一棵树加最少的边使得每个点只属于一个环。对于一棵树来说只能存在三种情况:要么所有结点都已只属于一个环,要么所有的子结点都已只属于一个环,要么除了根结点和一条路径(其余都已成环),这种情况可以跟别的树成环。所以用f[i][3]表示上述三种状态。注意两点成环不叫环。。。
pku3140Contestants Division 给一无向图(不是树),每点有一权值,将图一分为二,使得两部分的权值和相差最小。先用Tarjan缩点,f[i]表示以i为根结点的树的权值和,那么就是找最接近所有权值一半的树了。
一些链接:http://wenku.baidu.com/view/014564b069dc5022aaea00ba.html
http://www.cnblogs.com/crazyac/articles/1975734.html
21:33:51