標籤:
Apple Tree
Description
Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each node has an amount of apples. Wshxzt starts her happy trip at one node. She can eat up all the apples in the nodes she reaches. HX is a kind guy. He knows that eating too many can make the lovely girl become fat. So he doesn’t allow Wshxzt to go more than K steps in the tree. It costs one step when she goes from one node to another adjacent node. Wshxzt likes apple very much. So she wants to eat as many as she can. Can you tell how many apples she can eat in at most K steps.
Input
There are several test cases in the input
Each test case contains three parts.
The first part is two numbers N K, whose meanings we have talked about just now. We denote the nodes by 1 2 ... N. Since it is a tree, each node can reach any other in only one route. (1<=N<=100, 0<=K<=200)
The second part contains N integers (All integers are nonnegative and not bigger than 1000). The ith number is the amount of apples in Node i.
The third part contains N-1 line. There are two numbers A,B in each line, meaning that Node A and Node B are adjacent.
Input will be ended by the end of file.
Note: Wshxzt starts at Node 1.
Output
For each test case, output the maximal numbers of apples Wshxzt can eat at a line.
Sample Input
2 1 0 111 23 20 1 21 21 3
Sample Output
112
【題意】
一顆樹,n個點(1-n),n-1條邊,每個點上有一個權值,求從1出發,走V步,最多能遍曆到的權值。
【分析】
這題做太久了我太傻逼了所以要寫部落格。
每天都智障24小時。。一開始還看錯範圍,醉。。
這題感覺很依賴,於是我首先打dfs序那種的樹形依賴,然後發現我不會合并。
於是我去打子樹版本的,搞了超級久,整個一傻逼。
首先問題是我們是可以往回走,所以設f[i][j][0]表示在點i的子樹上走j步不往回走到i的最值,f[i][j][1]表示往回走。
一個點的子樹中不往回走只能有一個,注意不要漏啊不要重啊就好了。
f[x][j][1]=max(f[x][j][1],f[y][l][1]+f[x][j-l-1][1])
f[x][j][0]=max(f[x][j][0],f[y][l][0]+f[x][j-l][1])
f[x][j][0]=max(f[x][j][0],f[y][l][1]+f[x][j-l-1][0])
有一個地方就是一個子樹假設大小是size[x],那麼在這棵子樹上走的步數不會超過2*size[x],因為每條邊最多走兩次(走下去走上去),所以可以for到子樹大小的2倍,這樣可以最佳化到n^2。
感覺跟前面的依賴型還是有點不一樣,dfs序版的就不能解決,貌似,因為啊回來不回來那個好難搞
代碼如下:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 #define INF 0xfffffff10 #define Maxn 21011 12 struct node13 {14 int x,y,next;15 }t[2*Maxn];int len;16 17 int n,k;18 int first[Maxn],a[Maxn];19 20 int mymax(int x,int y) {return x>y?x:y;}21 22 void ins(int x,int y)23 {24 t[++len].x=x;t[len].y=y;25 t[len].next=first[x];first[x]=len;26 }27 28 int f[Maxn][Maxn][2],ans;29 30 void ffind(int x,int fa)31 {32 f[x][1][0]=f[x][1][1]=a[x];33 for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa)34 {35 int y=t[i].y;36 ffind(y,x);37 for(int j=k;j>=1;j--)38 {39 for(int l=1;l<=j;l++)40 {41 f[x][j][1]=mymax(f[x][j][1],f[y][l][1]+f[x][j-l-1][1]),//l+142 f[x][j][0]=mymax(f[x][j][0],f[y][l][0]+f[x][j-l][1]),43 f[x][j][0]=mymax(f[x][j][0],f[y][l][1]+f[x][j-l-1][0]);44 // f[x][l+1][0]=mymax(f[x][l+1][0],f[y][l][0]);45 }46 }47 }48 }49 50 int main()51 {52 while(scanf("%d%d",&n,&k)!=EOF)53 {54 ans=-INF;55 k++;56 for(int i=1;i<=n;i++) scanf("%d",&a[i]);57 len=0;58 memset(first,0,sizeof(first));59 for(int i=1;i<n;i++)60 {61 int x,y;62 scanf("%d%d",&x,&y);63 ins(x,y);ins(y,x);64 }65 memset(f,-63,sizeof(f));66 ffind(1,0);67 for(int i=1;i<=k;i++) ans=mymax(ans,mymax(f[1][i][0],f[1][i][1]));68 printf("%d\n",ans);69 }70 return 0;71 }[POJ 2486]
2016-10-15 11:19:19
【POJ 2486】 Apple Tree (樹形DP)