Pak Chanek has 𝑛n blank heart-shaped cards. Card 11 is attached directly to the wall while each of the other cards is hanging onto exactly one other card by a piece of string. Specifically, card 𝑖i (𝑖>1i>1) is hanging onto card 𝑝𝑖pi (𝑝𝑖<𝑖pi
In the very beginning, Pak Chanek must write one integer number on each card. He does this by choosing any permutation 𝑎a of [1,2,…,𝑛][1,2,…,n]. Then, the number written on card 𝑖i is 𝑎𝑖ai.
After that, Pak Chanek must do the following operation 𝑛n times while maintaining a sequence 𝑠s (which is initially empty):
After that, Pak Chanek will have a sequence 𝑠s with 𝑛n elements. What is the maximum length of the longest non-decreasing subsequence†† of 𝑠s at the end if Pak Chanek does all the steps optimally?
†† A sequence 𝑏b is a subsequence of a sequence 𝑐c if 𝑏b can be obtained from 𝑐c by deletion of several (possibly, zero or all) elements. For example, [3,1][3,1] is a subsequence of [3,2,1][3,2,1], [4,3,1][4,3,1] and [3,1][3,1], but not [1,3,3,7][1,3,3,7] and [3,10,4][3,10,4].
Input
The first line contains a single integer 𝑛n (2≤𝑛≤1052≤n≤105) — the number of heart-shaped cards.
The second line contains 𝑛−1n−1 integers 𝑝2,𝑝3,…,𝑝𝑛p2,p3,…,pn (1≤𝑝𝑖<𝑖1≤pi
Output
Print a single integer — the maximum length of the longest non-decreasing subsequence of 𝑠s at the end if Pak Chanek does all the steps optimally.
Examples
input
6 1 2 1 4 2
output
4
input
2 1
output
2
题意: 给出一棵树的结构,然后为树上每点分配点权,点权必须是一个排列,然后可以选择一个叶子结点,将其从树上删除并把它的权值放到串s中,如果该点点权小于父节点点权,则将其父节点点权修改为该点点权,问最终s串的非递降子序列最长长度。
分析: 设dp[i][0]表示不选i点时在其子树中能构成的最长子序列长度,dp[i][1]表示选i点时在其子树中能构成的最长子序列长度,可以发现,i点一定是其子树中最小的点,当选中i点后,要想非递减子序列最长,那么前面选的值必须和i点值相同,于是可以将那个最小值放在最长链的叶子结点上,这样整条链都是那个最小值了,所以dp[i][1] = i点的深度。而不选i点时,其子节点可选可不选,取一个最大值加起来就是dp[i][0]了,至于为什么可以加和,这是由于一开始构造的时候我们可以让不同子树对应不同的取值范围,这样就可以长度相加了。
具体代码如下:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- using namespace std;
-
- vector<int> to[100005];
- int dp[100005][2];//0表示不取i点,1表示取i点
-
- void dfs(int now, int fa){
- dp[now][0] = 0;
- dp[now][1] = 1;
- int mx = 0;
- for(int i = 0; i < to[now].size(); i++){
- int v = to[now][i];
- if(v == fa) continue;
- dfs(v, now);
- dp[now][0] += max(dp[v][0], dp[v][1]);
- mx = max(mx, dp[v][1]);
- }
- dp[now][1] += mx;
- }
-
- signed main()
- {
- int n;
- scanf("%d", &n);
- for(int i = 2; i <= n; i++){
- int fa;
- scanf("%d", &fa);
- to[fa].push_back(i);
- to[i].push_back(fa);
- }
- dfs(1, 0);
- printf("%d\n", max(dp[1][0], dp[1][1]));
-
- return 0;
- }
-