非常好的一道思维性题目,想了很久才想出来qwq(我好笨啊)

考虑a[]数组有什么用,首先可以yy出一些性质 (设num[i]为原来第i个位置的数是什么 , 因为题目说至少有一个排列可以满足a[],所以我们就假设num[]没有相同的元素):

1. 当 a[i] == a[j] 且 i<j 的时候,我们可以得出 num[i] > num[j] ,因为如果反过来的话 a[j] 就至少是 a[i]+1 了。

2. 对于任意一个 a[i] ,考虑所有 a[j] + 1 == a[i] 的 j,它们中至少有一个要满足 : num[j] < num[i];而很显然,因为上一个性质的传递性,所以只需要找到最大的 j 然后让num[j] < num[i] 就好了,也就是说每个 位置 至多 会和前面的一个位置 有必然的大小关系。

然后我们把<当作边,可以发现原图变成了一个森林。而现在我们的任务就是:求出原序列的一个拓扑排序,使得反向lis和最大。

这个好像还不是很容易啊,填一个数带来的影响太多了。

不过我们最初内心肯定都会有一个想法:贪心,尽量让靠后的位置匹配小的数。

但是我一开始心里有一个顾虑: 如果一个位置很靠后,但是因为它必须要小于一个很靠前的位置(或者说它的爸爸编号很小),从而被耽误导致答案很劣怎么办?

不过画图之后证明这种情况是不存在的!

可以发现森林的第i层就是由 所有 a[x] == i 的 x 组成的,而每个节点会向上一层最大的 编号小于自己的点 连边,所以这就保证了一种贪心的正确性:我们从虚根(0)开始,采取每次走编号最大的儿子的先序遍历策略。

这种贪心的正确性在于,我们在走一个点i之前经过的点,要么是i的祖先(钦定要比它小的),要么编号比i大(编号靠后的小答案更优)。

于是就做完了hhhhhhhh(虽然代码被我压得很短)

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int maxn=100005;
vector<int> g[maxn];
int n,m,pre[maxn],A,num[maxn],now,f[maxn],M[maxn];
inline void update(int x,int y){ for(;x<=n;x+=x&-x) f[x]=max(f[x],y);}
inline int query(int x){ int an=0; for(;x;x-=x&-x) an=max(an,f[x]); return an;}
void dfs(int x){ if(x) num[x]=++now; for(int i=g[x].size()-1;i>=0;i--) dfs(g[x][i]);}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&A),g[pre[A-1]].pb(i),pre[A]=i;
dfs(0); ll ans=0;
for(int i=n;i;i--) M[i]=query(num[i]-1)+1,update(num[i],M[i]),ans+=(ll)M[i];
printf("%lld\n",ans);
return 0;
}

  

[TJOI2014] Alice and Bob的更多相关文章

  1. [TJOI2014]Alice and Bob[拓扑排序+贪心]

    题意 给出一个序列的以每一项结尾的 \(LIS\) 的长度a[],求一个序列,使得以每一项为开头的最长下降子序列的长度之和最大. \(n\leq 10^5\) . 分析 最优解一定是一个排列,因为如果 ...

  2. [BZOJ 5158][Tjoi2014]Alice and Bob

    传送门 \(\color{green}{solution}\) 贪心 /************************************************************** P ...

  3. [bzoj5158][Tjoi2014]Alice and Bob

    好羞愧啊最近一直在刷水... 题意:给定序列$c$的$a_i$,构造出一个序列$c$使得$\sum b_i$最大. 其中$a_i$表示以$c_i$结尾的最长上升子序列长度,$b_i$表示以$c_i$为 ...

  4. BZOJ5158 [Tjoi2014]Alice and Bob 【贪心 + 拓扑】

    题目链接 BZOJ5158 题解 题中所给的最长上升子序列其实就是一个限制条件 我们要构造出最大的以\(i\)开头的最长下降子序列,就需要编号大的点的权值尽量小 相同时当然就没有贡献,所以我们不妨令权 ...

  5. 关于TJOI2014的一道题——Alice and Bob

    B Alice and Bob •输入输出文件: alice.in/alice.out •源文件名: alice.cpp/alice.c/alice.pas • 时间限制: 1s 内存限制: 128M ...

  6. 2016中国大学生程序设计竞赛 - 网络选拔赛 J. Alice and Bob

    Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  7. bzoj4730: Alice和Bob又在玩游戏

    Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...

  8. Alice and Bob(2013年山东省第四届ACM大学生程序设计竞赛)

    Alice and Bob Time Limit: 1000ms   Memory limit: 65536K 题目描述 Alice and Bob like playing games very m ...

  9. sdutoj 2608 Alice and Bob

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2608 Alice and Bob Time L ...

随机推荐

  1. "帮你"-用户模板和用户场景

    场景/故事/story 典型用户: 用户性质 典型用户介绍 姓名 小李 年龄 20岁 职业 学生 代表的用户在市场上的比例和重要性 代表学校内广大普通学生,因此有很大的重要性. 使用本软件的典型场景 ...

  2. jQuery+Asp.net 实现简单的下拉加载更多功能

    原来做过的商城项目现在需要增加下拉加载的功能,简单的实现了一下.大概可以整理一下思路跟代码. 把需要下拉加载的内容进行转为JSON处理存在当前页面: <script type="tex ...

  3. 创建 PSO

    TechNet 库 Windows Server Windows Server 2008 R2 und Windows Server 2008 浏览 Windows Server 技术 Active ...

  4. IOS开发---菜鸟学习之路--(一)

    PS(废话): 看了那么多的博客文章,发现大部分人都一直在强调写技术博客的重要性,索性自己也耐着性子写写看吧. 写博客的重要性之类的说明,我就不做复制黏贴的工作了.因为自己没有写过多少,所也不清楚是不 ...

  5. 【Best Time to Buy and Sell Stock II】cpp

    题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  6. allocator class

    当分配一大块内存时,我们通常计划在这块内存上按需构造对象,这样的我们希望将内存分配和对象构造分离.但是通常的new关键字的分配的动态空间,有时候会造成一些浪费,更致命的是“如果一个类没有默认构造函数, ...

  7. Log4j官方文档翻译(三、配置)

    之前的章节介绍了log4j的核心组件,本章将会通过配置文件介绍一下核心组建的配置. 主要在配置文件中配置log4j的日志级别,定义appender.layout等. log4j.properties是 ...

  8. mapserv和mapserv.exe的区别

    哎,困扰了我这么久才知道一个是在unix环境下的,一个是在windows环境下的

  9. BZOJ-2618 [CQOI2006]凸多边形

    半平面交模版题.. #include <cstdlib> #include <cstdio> #include <cmath> #include <cstri ...

  10. BZOJ 3897: Power

    3897: Power Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 218  Solved: 83[Submit][Status][Discuss] ...