Codeforces Round #279 (Div. 2) F
来源:互联网 发布:平安证券行情交易软件 编辑:程序博客网 时间:2024/05/01 23:10
2014/11/26
说是看题解,其实只是随便找了个代码撸,看懂了就赚了,看不懂就当运气不好。
你们不写我写。
朴素做法:将每个点作为根 dfs出来路径然后求最长上升子序列长度。(如果你试过,恭喜)
脑洞打开做法:
将每个点作为根dfs出来路径O(n^2),求最长上升子序列是 O(n^2)的时间,总共是 n^4,所以在找最长长度的时候需要改(打)变(开)一下策(脑)略(洞)
在dfs到某个节点 S 的时候,(根节点确定,其到根节点的路径唯一)你可以得出在这条路径上 如果以S为终点,得出的最长路径的长度。
然后弄个排列 从小到大 a[1] a[2] a[3] a[4] ,假如 将S点加入最长路径 Max S = 2(以S为最长路径的终点),更新a[ 2 ] = S的值;
弄个栈 q[ x ] 表示当最长上升子序列长度为X时 在 序列中排列第 X 的节点值
举个例子:
以求出的最长上升子序列:
1 4 5
栈 1: 1
栈 2: 4
栈 3: 5
如果下一个节点 值为 6 6加入栈 4
如果 下一个节点值为 2 2加入栈 1
如此,你就可以在dfs的同时用O(1)时间找出 以 当前节点为终点的最长子序列长度 X
可想而知 Max( x )就是题目所求的值。
(我知道上面的你们没看懂,我写完后也看不懂,主要就是一个利用 lower_bound 来找出节点X在路径上的大小排名,(即以它为终点时的最长子序列长度),然后实时更新,那个记录节点值的长度数组)
还是撸代码吧,lower_bound (ans,ans+6005,v[ x ]) - ans; ans[ x ] = v[ x ];
有意思的地方还有很多,代码的魅力就是几行能够抵上几十行。
#include<stdio.h>#include<string.h>#include<vector>#include<stack>#include<algorithm>using namespace std;vector<int> mp[6005];int a[6005];int ans[6005];stack<int> q[6005];int cnt , maxn ;int Max(int a,int b){return a>b?a:b;}void init(){for(int i = 0;i < 6005; i++){mp[i].clear();}}void dfs(int res,int p = -1){ int x = lower_bound(ans,ans+6005,a[res]) - ans; q[x].push(ans[x]); ans[x] = a[res]; maxn = Max(maxn,x);for(int i = 0;i < mp[res].size(); i++){if(mp[res][i]!= p){dfs(mp[res][i] , res);}}ans[x] = q[x].top(); <span style="font-family: Arial, Helvetica, sans-serif;">//重点在于,你要恢复记录长度的长度数组ans 这条路径只走到 res这个点的时候 节点排列。</span>
q[x].pop(); <span style="font-family: Arial, Helvetica, sans-serif;">//dfs完“往回走” 的时候别忘记清除之前记录的数据</span>return ;
}int main(){int n , r, l;while(~scanf("%d",&n)){maxn = 0;init();for(int i = 1;i <= n; i++)scanf("%d",&a[i]); for(int i = 0;i < n-1; i++) { scanf("%d%d",&l,&r); mp[l].push_back(r); mp[r].push_back(l); } for(int i =0 ;i < 6005; i++) {ans[i] = 11000000;} for(int i = 1;i <= n; i++) { dfs(i); } printf("%d\n",maxn + 1); }return 0;}
- Codeforces Round #279 (Div. 2) F
- Codeforces Round #279 (Div. 2) F
- Codeforces Round #279 (Div. 2) B F
- Codeforces Round #279 (Div. 2) F. Treeland Tour
- Codeforces Round #277.5 (Div. 2) F
- Codeforces Round #277.5 (Div. 2)F题
- Codeforces Round #322 (Div. 2) F
- Codeforces Round #377 (Div. 2) F
- Codeforces Round #386 (Div. 2) F
- Codeforces Round #441 Div. 2 E,F
- Codeforces Round #442 (Div. 2) 877 F
- Codeforces Round 864F (Codeforces Round #436 Div. 2) F. Cities Excursions tarjan判环
- Codeforces Beta Round #95 (Div. 2) F - Present to Mom
- Codeforces Round #271 (Div. 2)F. Ant colony(线段树)
- Codeforces Round #277.5 (Div. 2) F. Special Matrices
- Codeforces Round #Pi (Div. 2) F. Mausoleum DP
- DP Codeforces Round #322 (Div. 2) F. Zublicanes and Mumocrates
- Codeforces Round #346 (Div. 2) F bfs+并查集
- spice 协议相关分析总结
- C# SendKeys.SendWait 方法和SendKeys.Send 方法区别
- 文件上传
- UIAleartView 改变输入框的样式
- 【设计模式篇】Android设计模式之-观察者模式 自我见解
- Codeforces Round #279 (Div. 2) F
- 查看csdn的收藏
- iOS基础5:常见呈现模式
- 找源码
- 博客里程碑
- 实现lua和c/c++互调
- npm常用命令
- C#winform程序安装时自动卸载新版本覆盖旧版本
- Console命令详解,让调试js代码变得更简单