瞎搞DP 改造二叉树
问题 C: 改造二叉树
时间限制: 1 Sec 内存限制: 128 MB题目描述
输入
3
2 2 2
1 0
1 1
输出
2
提示
考试时居然有人看成了树规。。。把中序遍历搞出来就成了单调上升,但是单调不下降子序列最好求。。
新技巧:把a[i]-i.这样就变成单调不下降的了。
对n^2进行优化:记录长度为i的不下降的子序列最小a[i]进行记录,upper_bound进行查就行了。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define N 100000 #define inf 1000000000 using namespace std; int read() { int sum=0,f=1;char x=getchar(); while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();} while(x>='0'&&x<='9'){sum=(sum<<3)+(sum<<1)+x-'0';x=getchar();} return sum*f; } int n,a[N+5],lc[N+5],rc[N+5],val[N+5],cnt; int f[N+5],t[N+5]; void tree(int x) { if(lc[x])tree(lc[x]); val[++cnt]=a[x]; if(rc[x])tree(rc[x]); } int main() { // freopen("binary18.in","r",stdin); // freopen("binary.out","w",stdout); n=read(); memset(t,120,sizeof(t)); for(int i=1;i<=n;i++)a[i]=read(); int x,y; for(int i=2;i<=n;i++) { x=read(); y=read(); if(y==0)lc[x]=i; else rc[x]=i; } tree(1); int ans=0; for(int i=1;i<=n;i++)val[i]-=i; for(int i=1;i<=n;i++) { int k=upper_bound(t+1,t+n+1,val[i])-t; f[i]=k; ans=max(ans,f[i]); t[k]=min(t[k],val[i]); }//cout<<ans<<" "; printf("%d\n",n-ans); }