• 3743. 【TJOI2014】Alice and Bob


    题目

    有一个(n)的排列。
    给你每个位置结尾的最长上升子序列的长度(a_i),让你构造这个排列使得每个位置开头的最长下降子序列的长度之和最大。


    思考历程

    贪心一直都不是我的强项……
    我比赛的时候是想着如何用差分约束之类的东西搞的:
    对于每个(a_i),找到前面的(a_j=a_i-1),它们至少有一个满足(x_j)小于(x_i)
    对于前面的每个(a_jgeq a_i)(x_j)都大于(x_i)
    然后我发现我不会连边……因为“至少”这个东西太恶心了……


    正解

    贪心的精髓在于钦定。
    有个不怎么显然的策略就是:将大的尽量往前放,小的尽量往后放。
    按照这个策略,就可以钦定一些东西:
    对于所有的(a_j=a_i-1),取最后一个(j),钦定(a_j<a_i)。因为(a_i)限制了前面满足条件的(j)的其中一个,所以将这个放在最后是最优的策略。
    对于前面的(a_j=a_i),取最后一个(j),钦定(a_j>a_i)。这是为了保证构造出来的序列的正确性。
    容易发现,这样处理之后前面的每个(a_jgeq a_i)(j)都会直接或间接地满足条件。
    将这些限制关系连边,跑拓扑。
    跑的时候用个堆,将小的尽量往后放。


    代码

    using namespace std;
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 100010
    #define ll long long
    int n;
    int a[N];
    int buc[N];
    int q[N];
    bool cmpq(int son,int fa){return son>fa;}
    int to[N],to2[N],d[N];
    int v[N];
    int t[N];
    void add(int x,int c){
    	for (;x<=n;x+=x&-x)
    		t[x]=max(t[x],c);
    }
    int query(int x){
    	int res=0;
    	for (;x;x-=x&-x)
    		res=max(res,t[x]);
    	return res;
    }
    int main(){
    	freopen("alice.in","r",stdin);
    	freopen("alice.out","w",stdout);
    	scanf("%d",&n);
    	for (int i=1;i<=n;++i){
    		scanf("%d",&a[i]);
    		to[i]=buc[a[i]-1];
    		d[to[i]]++;
    		if (buc[a[i]]){
    			to2[buc[a[i]]]=i;
    			d[i]++;
    		}
    		buc[a[i]]=i;
    	}
    	int nh=0;
    	for (int i=1;i<=n;++i)
    		if (d[i]==0)
    			q[nh++]=i;
    	int num=n;
    	while (nh){
    		int x=q[0];
    		pop_heap(q,q+nh--,cmpq);
    		v[x]=num--;
    		if (to[x] && !--d[to[x]]){
    			q[nh++]=to[x];
    			push_heap(q,q+nh,cmpq);
    		}
    		if (to2[x] && !--d[to2[x]]){
    			q[nh++]=to2[x];
    			push_heap(q,q+nh,cmpq);
    		}
    	}
    	ll ans=0;
    	for (int i=n;i>=1;--i){
    		int f=query(v[i]-1)+1;
    		ans+=f;
    		add(v[i],f);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    总结

    在贪心问题中,钦定是关键。

  • 相关阅读:
    搭建公共DNS服务器[转]
    zabbix3.4 yum快速安装
    centos7安装图形化界面并远程连接
    记一次排查黑客入侵
    centos6安装图形界面并远程连接
    树莓派做NAS
    document.documentElement.scrollTop||document.body.scrollTop;
    矩阵连乘
    母函数详解
    Catalan 数
  • 原文地址:https://www.cnblogs.com/jz-597/p/12161989.html
Copyright © 2020-2023  润新知