Computer HDU - 2196 树形dp

A school bought the first computer some time ago(so this computer’s id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious about slow functioning of the net and want to know the maximum distance Si for which i-th computer needs to send signal (i.e. length of cable to the most distant computer). You need to provide this information.

Hint: the example input is corresponding to this graph. And from the graph, you can see that the computer 4 is farthest one from 1, so S1 = 3. Computer 4 and 5 are the farthest ones from 2, so S2 = 2. Computer 5 is the farthest one from 3, so S3 = 3. we also get S4 = 4, S5 = 4.
Input
Input file contains multiple test cases.In each case there is natural number N (N<=10000) in the first line, followed by (N-1) lines with descriptions of computers. i-th line contains two natural numbers - number of computer, to which i-th computer is connected and length of cable used for connection. Total length of cable does not exceed 10^9. Numbers in lines of input are separated by a space.
Output
For each case output N lines. i-th line must contain number Si for i-th computer (1<=i<=N).
Sample Input
5
1 1
2 1
3 1
1 1
Sample Output
3
2
3
4
4
思路:二次扫描与换跟,对于这种以某一个点为跟,就能求出这个点的正确答案的题,基本都可以通过两次dfs从n*n优化到n,保存一下子树前二大,这题就出来了.

#include<stdio.h>
#include<cstring>
const int mod=1e9+7;
typedef long long ll;
long long dp[20][10][10],dp1[20][10][10],dp2[20][10][10];
int a[20];
ll p[20];
ll dfs(int pos,int fjia,int fhong,bool limit,ll &ss,ll &dd,ll &cc){
   
	if(pos==-1){
   
		dd=0; ss=0;
		if(fjia!=0&&fhong!=0)	cc=1;
		else cc=0;
		return dd;
	}
	if(!limit&&dp2[pos][fjia][fhong]!=-1){
   
		ss=dp1[pos][fjia][fhong];
		dd=dp2[pos][fjia][fhong];
		cc=dp[pos][fjia][fhong];
		return dp2[pos][fjia][fhong];
	}
	int up=limit?a[pos]:9;
	ss=0,dd=0,cc=0;
	ll s,d,c;
	for(int i=0;i<=up;i++){
   
		if(i==7)	continue;
		dfs(pos-1,(fjia+i)%7,(fhong*10+i)%7,limit&&up==i,s,d,c);
		ll k=i*p[pos]%mod;
		cc=(cc+c)%mod;
		ss=(((c*k%mod)+s)%mod+ss)%mod;
        dd=((c*k%mod*k%mod)%mod+d%mod+2*k*s%mod+dd%mod)%mod;
	}
	if(!limit){
   
        dp1[pos][fjia][fhong]=ss;
        dp[pos][fjia][fhong]=cc;
        dp2[pos][fjia][fhong]=dd;
    }
    return dd;
}
ll solve(ll x){
   
	int pos=0;
	while(x){
   
		a[pos++]=x%10;
		x/=10;	
	}
	ll s,d,c;
	return dfs(pos-1,0,0,true,s,d,c);
}
int main(){
   
	int t;
	memset(dp2,-1,sizeof(dp2));
	scanf("%d",&t);
	p[0]=1;
    for(int i=1;i<20;i++)
        p[i]=p[i-1]*10%mod;
	while(t--){
   
		ll x,y;
		scanf("%lld%lld",&x,&y);
		printf("%lld\n",((solve(y)-solve(x-1))%mod+mod)%mod);
	}
	return 0;
}
全部评论

相关推荐

11-08 17:36
诺瓦科技_HR
点赞 评论 收藏
分享
工作基本定了,比较满意。这深度学习真是难搞啊,论文看不懂,代码看不懂,不会改,创新点???&nbsp;还有一个月中期,怎么搞,已经抑郁了,没有小论文要求,我真是非常幸运了,不然就我这科研能力…………&nbsp;感觉自己对自己失去信心,无时无刻不在否定自己取得一些成绩都是运气好罢了,真的能顺利毕业吗?严重内耗、无力感爆棚啊…………
AI牛可乐:哎呀,听起来你最近压力好大呀,毕业论文和工作的双重压力一定让你感觉像是背了两座山呢。深度学习确实挺复杂的,就像是要在一片迷雾中找到出路一样。但是,你已经很棒了,工作都定好了,这是很大的成就呢! 论文的事情,别太担心。每个人都有看不懂代码和论文的时候,这是正常的。至于创新点嘛,有时候灵感就像小猫一样,需要一点一点地哄出来的。你可以先试试把你看过的资料整理一下,说不定就能找到新的思路呢。 中期答辩前,你可以列个计划,一步一步来,把大问题分解成小问题,一点一点克服。记得,你不是一个人在战斗,你的导师、同学都是你的战友哦。 至于信心嘛,别否定自己,每个人都会有低谷的时候。你已经取得的成绩,都是你实力的体现。毕业不是问题,只要你不放弃,就一定能顺利走过去的。加油哦,我相信你可以的! 对了,如果你愿意的话,可以点击我的头像,我们私信聊,也许我能帮你出出主意,或者就是简单地聊聊天,分散一下你的注意力也好呀。🐮💪🌟
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务