树形dp.docx

上传人:b****5 文档编号:6655282 上传时间:2023-01-08 格式:DOCX 页数:29 大小:26.56KB
下载 相关 举报
树形dp.docx_第1页
第1页 / 共29页
树形dp.docx_第2页
第2页 / 共29页
树形dp.docx_第3页
第3页 / 共29页
树形dp.docx_第4页
第4页 / 共29页
树形dp.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

树形dp.docx

《树形dp.docx》由会员分享,可在线阅读,更多相关《树形dp.docx(29页珍藏版)》请在冰豆网上搜索。

树形dp.docx

树形dp

树形dp

Anniversaryparty

TimeLimit:

2000/1000MS(Java/Others)    MemoryLimit:

65536/32768K(Java/Others)

TotalSubmission(s):

7954    AcceptedSubmission(s):

3462

ProblemDescription

Thereisgoingtobeapartytocelebratethe80-thAnniversaryoftheUralStateUniversity.TheUniversityhasahierarchicalstructureofemployees.ItmeansthatthesupervisorrelationformsatreerootedattherectorV.E.Tretyakov.Inordertomakethepartyfunnyforeveryone,therectordoesnotwantbothanemployeeandhisorherimmediatesupervisortobepresent.Thepersonnelofficehasevaluatedconvivialityofeachemployee,soeveryonehassomenumber(rating)attachedtohimorher.Yourtaskistomakealistofguestswiththemaximalpossiblesumofguests'convivialityratings.

Input

Employeesarenumberedfrom1toN.AfirstlineofinputcontainsanumberN.1<=N<=6000.EachofthesubsequentNlinescontainstheconvivialityratingofthecorrespondingemployee.Convivialityratingisanintegernumberinarangefrom-128to127.AfterthatgoTlinesthatdescribeasupervisorrelationtree.Eachlineofthetreespecificationhastheform:

 

LK 

ItmeansthattheK-themployeeisanimmediatesupervisoroftheL-themployee.Inputisendedwiththeline 00

Output

Outputshouldcontainthemaximalsumofguests'ratings.

SampleInput

7

1

1

1

1

1

1

1

13

23

64

74

45

35

00

SampleOutput

5

题意:

一个公司要举办party,不过每一个员工都不愿意和自己的上级在一起,因为这样自己会不开心,而每个人参加party都有一个开心的程度,同时给出来上下级之间的关系,让我们求最大的开心程度是多少。

这题用来树形dp入门,首先就是如何来建树的问题和怎样dp的问题,我们直接用一个数组f[i]来表示第i个人的上司是谁,这样通过层层递进来找到最大的大boss,也就是一棵树的根,然后,用dfs的方式来进行层层搜索,同时dp。

具体的dp过程也就是用dp[i][0]表示如果这个人不来时候的最大开心程度,dp[i][1]表示这个人来的时候的最大开心程度,如果树上面的父亲节点x不来,那么dp[x][0]+=max(dp[i][0],dp[i][1]);,如果树上的父亲节点x来(意味着子节点不会来),那么dp[x][1]+=dp[i][0];

#include

#include

#include

#include

#include

#include

#include

usingnamespacestd;

typedeflonglongll;

constintN=6010;

intm,n;

intdp[N][2],rd[N];

vectortu[N];

voiddfs(intx)

{

intl=tu[x].size();

for(inti=0;i

{

intt=tu[x][i];

dfs(t);

dp[x][0]+=max(dp[t][1],dp[t][0]);

dp[x][1]+=dp[t][0];

}

}

intmain()

{

while(~scanf("%d",&n))

{

for(inti=1;i<=n;i++)

tu[i].clear();

memset(rd,0,sizeof(rd));

for(inti=1;i<=n;i++)

{

scanf("%d",&dp[i][1]);

dp[i][0]=0;

}

intx,y;

while(~scanf("%d%d",&x,&y)&&x+y)

tu[y].push_back(x),rd[x]++;

intans=-1;

for(inti=1;i<=n;i++)

if(rd[i]==0)///防止不止一个根节点

{dfs(i);ans=max(ans,max(dp[i][0],dp[i][1]));}

cout<

}

}

Themore,TheBetter

TimeLimit:

6000/2000MS(Java/Others)    MemoryLimit:

32768/32768K(Java/Others)

TotalSubmission(s):

6868    AcceptedSubmission(s):

4033

ProblemDescription

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个城堡所获得的最多宝物的数量。

SampleInput

32

01

02

03

74

22

01

04

21

71

76

22

00

SampleOutput

5

13

虽然是树形dp,可是其dp方式看起来有点像区间dp(总归来说,其实二维dp也就是这样的了。

这题的dp有点不好想,不过其实仔细看还是可以看懂的。

用dp[i][j]表示第i个点攻克j个城堡获得的最大财富。

若t是i的一个子节点,那么dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[t][k]);

这个dp方程真心不好想。

还有一点是我们要防止j大于了m,所以dfs里边加上一个变量,使最多只有m次。

当然,我首先就把m++了,因为我引入了0这个节点来连接所有树的根节点,这样就做到了把森林连成了树!

#include

#include

#include

#include

#include

#include

#include

#definem(a,b)memset(a,b,sizeof(a))

usingnamespacestd;

typedeflonglongll;

constintN=250;

intdp[N][N],vis[N];

intm,n;

vectortu[N];

voiddfs(intx,intmm)

{

vis[x]=1;

intl=tu[x].size();

for(inti=0;i

{

intt=tu[x][i];

if(!

vis[t])

dfs(t,mm-1);

for(intj=mm;j>=1;j--)//j的上下界比较好想,不过一定要注意j是从大到小在变化的。

for(intk=1;k

dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[t][k]);

}

}

intmain()

{

while(cin>>n>>m&&m+n)

{

m++;

m(dp,0);

m(tu,0);

m(vis,0);

for(inti=1;i<=n;i++)

{

inta,b;

cin>>a>>b;

tu[a].push_back(i);

dp[i][1]=b;

}

dfs(0,m);

printf("%d\n",dp[0][m]);

}

return0;

}

F.ZublicanesandMumocrates

timelimitpertest

  3seconds

memorylimitpertest

  512megabytes

input

  standardinput

output

  standardoutput

It'selectiontimeinBerland.Thefavoritesareofcoursepartiesofzublicanesandmumocrates.Theelectioncampaignsofbothpartiesincludenumerousdemonstrationson n mainsquaresofthecapitalofBerland.Eachofthe n squarescertainlycanhavedemonstrationsofonlyoneparty,otherwiseitcouldleadtoriots.Ontheotherhand,bothpartieshaveappliedtohostahugenumberofdemonstrations,sothatonallsquaresdemonstrationsmustbeheld.Nowthecapitalmanagementwilldistributetheareabetweenthetwoparties.

Somepairsofsquaresareconnectedby (n - 1) bidirectionalroadssuchthatbetweenanypairofsquaresthereisauniquewaytogetfromonesquaretoanother.Somesquaresareontheoutskirtsofthecapitalmeaningthattheyareconnectedbyaroadwithonlyoneothersquare,suchsquaresarecalled deadend squares.

Themayorofthecapitalinstructedtodistributeallthesquaresbetweenthepartiessothatthe deadend squareshadthesamenumberofdemonstrationsofthefirstandthesecondparty.Itisguaranteedthatthenumberofdeadendsquaresofthecityiseven.

Topreventpossibleconflictsbetweenthezublicanesandthemumocratesitwasdecidedtominimizethenumberofroadsconnectingthesquareswiththedistinctparties.You,asadeveloperofthedepartmentofdistributingsquares,shoulddeterminethissmallestnumber.

Input

Thefirstlineoftheinputcontainsasingleinteger n (2 ≤ n ≤ 5000)—thenumberofsquaresinthecapitalofBerland.

Next n - 1 linescontainthepairsofintegers x, y (1 ≤ x, y ≤ n, x ≠ y)—thenumbersofthesquaresconnectedbytheroad.Allsquaresarenumberedwithintegersfrom 1 to n.Itisguaranteedthatthenumberofdeadendsquaresofthecityiseven.

Output

Printasinglenumber—theminimumnumberofroadsconnectingthesquareswithdemonstrationsofdifferentparties.

Sampletest(s)

input

8

14

24

34

65

75

85

45

output

1

input

5

12

13

14

15

output

2

题意:

给出一个树,要求最少删除多少条边之后使叶子节点恰好平分。

思路:

树形dp,用dp[i][j]表示节点i删除j个叶子节点所需要的最短的步数

#include

#include

#include

#include

#include

#include

#include

usingnamespacestd;

typedeflonglongll;

constintN=5001,INF=999999999;

vectortu[N];

intz[N];///某个节点的叶子节点数

intdp[N][N];///dp[i][j]表示叶子节点i删除j个节点所需要的最短的步数

intn;

voiddfs(intnow,intpre)

{

if(tu[now].size()==1)

z[now]=1;

elsez[now]=0;

dp[now][0]=0;

for(inti=1;i<=n;i++)

dp[now][i]=INF;

intl=tu[now].size();

for(inti=0;i

{

intnext=tu[now][i];

if(next==pre)continue;

dfs(next,now);

for(intj=z[now];j>=0;j--)///必须逆序

for(intk=0;k<=z[next];k++)

dp[now][j+k]=min(dp[now][j+k],dp[now][j]+dp[next][k]);///状态转移

z[now]+=z[next];

}

for(inti=0;i<=z[now];i++)

dp[now][i]=min(dp[now][i],dp[now][z[now]-i]+1);///把now节点算进去,删除i个叶节点相当于一刀把now节点连接父亲的边删掉(所有叶节点删掉之后,相当于代码+1操作)再把z[now]-i个本来不打算删掉的叶节点删回来

}

intmain()

{

scanf("%d",&n);

if(n==2)

{

puts("1");

return0;

}

memset(dp,0,sizeof(dp));

for(inti=0;i

{

inta,b;

scanf("%d%d",&a,&b);

tu[a].push_back(b);

tu[b].push_back(a);

}

introot=1;

while(tu[root++].size()==1);

dfs(root,0);

printf("%d\n",dp[root][z[root]/2]);

}

Mahjongtree

TimeLimit:

6000/3000MS(Java/Others)    MemoryLimit:

65536/65536K(Java/Others)

TotalSubmission(s):

1660    AcceptedSubmission(s):

521

ProblemDescription

Littlesunisanartist.Todayheisplayingmahjongalone.Hesuddenlyfeelsthatthetreeintheyarddoesn'tlookgood.Sohewantstodecoratethetree.(Thetreehasnvertexs,indexedfrom1ton.)

Thoughtforalongtime,finallyhedecidestousethemahjongtodecoratethetree.

Hismahjongisstrangebecauseallofthemahjongtileshadadistinctindex.(Littlesunhasonlynmahjongtiles,andthemahjongtilesindexedfrom1ton.)

Heputthemahjongtilesonthevertexsofthetree.

Asisknowntoall,littlesunisanartist.Sohewanttodecoratethetreeasbeautifulaspossible.

Hisdecorationrulesareasfollows:

(1)Placeexactonemahjongtileoneachvertex.

(2)Themahjongtiles'indexmustbecontinueswhichareplacedonthesonvertexsofavertex.

(3)Themahjongtiles'indexmustbecontinueswhichareplacedonthevertexsofanysubtrees.

Nowhewanttoknowthathecanobtainhowmanydifferentbeautifulmahjongtreeusingtheserules,becauseoftheanswercanbeverylarge,youneedoutputtheanswermodulo1e9+7.

Input

ThefirstlineoftheinputisasingleintegerT,indicatesthenumberoftestcases. 

Foreachtestcase,thefirstlinecontainsanintegersn.(1<=n<=100000)

Andthenextn-1lines,eachlinecontainstwointegersuiandvi,whichdescribesanedgeofthetree,andvertex1istherootofthetree.

Output

Foreachtestcase,outputoneline.Theoutputformatis"Case#x:

ans"(withoutquotes),xisthecasenumber,startingfrom1.

SampleInput

2

9

21

31

43

53

62

74

87

93

8

21

31

43

51

64

75

84

SampleOutput

Case#1:

32

Case#2:

16

题意:

有一棵有n个节点的树,有编号1~n的n个数字要放到树上,且要满足三个要求:

 

1.树的每个节点只放一个数字 

2.树的任意一个节点的所有直接孩子节点上面放的数字排序后是连续的 

3.一棵子树的所有节点上面放的数字排序后是连续的 

问有多少种不同的放法,结果取模1e9+7。

思路:

由于所有子树是连续的,所以可以用区间来表示子树,设要给当前子树编号为[1,n],如果当前子树是原树,那么根有两种选择,分别是放头和尾(如果n等于1,那么头和尾重合了,也就是只有1种选择),如果不是原树,那么根的选择是唯

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1