Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

雁过留声——最长不降子序列

Posted by fanhqme at 2009-12-13 14:38:22 on Problem 3214
看到“堆”这种形式,很容易让人联想到树状dp,但是,数据范围告诉我,没戏。
分析这题的特点,大约可以得到以下关键约束:
left<right<=root
换句话说,可以把所有的顶点排序,例如:
     a
    / \
   b   c
  /\   /\
 d  e f  g
则d<e<=b<f<g<=c<=a,
题目的意思就是修改某些值,使得这个式子成立。
怎么思考呢?
把题目的意思转化一下:保留数目尽量多的原始值,使得式子成立。
有思路了:
先把所有的<号转化为≤:
d<=e-1<=b-1<=f-2<=g-3<=c-3<=a-3
然后,对
d e-1 b-1 f-2 g-3 c-3 a-3跑一个最长不降子序列就ok乐!

关键代码:
void dfs(int a){
	if (a>=N)return;
	dfs((a<<1)+1);
	if ((a<<1)+2<N)delta++;
	dfs((a<<1)+2);
	q[pt++]=A[a]-delta;
}
        dfs(0);
	ml=0;
	for (int i=0;i<N;i++){
		if (ml){
			if (mn[1]>q[i])tmp=1;
			else if (mn[ml]<=q[i])tmp=ml+1;
			else{
				l=1;r=ml;
				while (r>l+1){
					if (mn[(r+l)>>1]<=q[i])l=((r+l)>>1);
					else r=((r+l)>>1);
				}
				tmp=l+1;
			}
			if (tmp>ml)mn[++ml]=q[i];
			else if (mn[tmp]>q[i])mn[tmp]=q[i];
		}else{
			mn[ml=1]=q[i];
		}
	}
	printf("%d\n",N-ml);

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator