Description

为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐。每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想所有第3批就餐的奶牛排在队尾,队伍的前端由设定为第1批就餐的奶牛占据,中间的位置就归第2批就餐的奶牛了。由于奶牛们不理解FJ的安排,晚饭前的排队成了一个大麻烦。 第i头奶牛有一张标明她用餐批次D_i(1 <= D_i <= 3)的卡片。虽然所有N(1 <= N <= 30,000)头奶牛排成了很整齐的队伍但谁都看得出来,卡片上的号码是完全杂乱无章的。 在若干次混乱的重新排队后,FJ找到了一种简单些的方法:奶牛们不动,他沿着队伍从头到尾走一遍把那些他认为排错队的奶牛卡片上的编号改掉,最终得到一个他想要的每个组中的奶牛都站在一起的队列,例如111222333或者333222111。哦,你也发现了,FJ不反对一条前后颠倒的队列,那样他可以让所有奶牛向后转,然后按正常顺序进入餐厅。 你也晓得,FJ是个很懒的人。他想知道,如果他想达到目的,那么他最少得改多少头奶牛卡片上的编号。所有奶牛在FJ改卡片编号的时候,都不会挪位置。

Input

第1行: 1个整数:N 第2..N+1行: 第i+1行是1个整数,为第i头奶牛的用餐批次D_i

Output

第1行: 输出1个整数,为FJ最少要改几头奶牛卡片上的编号,才能让编号变成他设想中的样子

Sample Input

5
1
3
2
1
1
输入说明:

队列中共有5头奶牛,第1头以及最后2头奶牛被设定为第一批用餐,第2头奶牛的预设是第三批用餐,第3头则为第二批用餐。

Sample Output

1

输出说明:

如果FJ想把当前队列改成一个不下降序列,他至少要改2头奶牛的编号,一种可行的方案是:把队伍中2头编号不是1的奶牛的编号都改成1。不过,如果FJ选择把第1头奶牛的编号改成3就能把奶牛们的队伍改造成一个合法的不上升序列了。

题解:

求出最长不下降子序列,正反各做一次,求最大的长度;

答案就为 n-maxl;

此题学习一下最长不下降子序列O(nlogn)的算法;

推导可见白书或是这里

我觉得可以通过理解代码理解原理:

	for(int i=1;i<=n;i++)
{
int k=lower_bound(g+1,g+n+1,a[i],cmp2)-g;
f[i]=k;
g[k]=a[i];
ans=max(ans,f[i]);
}

g可以理解为用来储存子序列,f为最长不下降子序列的长度;

lower_bound是在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置,具体的可以看这里

对于程序本身,我们可以这样理解:

找到第一个比a[i]大的元素的位置k,我们可以认为k就为当前找到的最长不下降子序列的长度;

用f记录下k;

把g[k]插在a[i]的前面(并不是替换),这样就可以前面的元素尽可能小,使下一步搜出来的k尽可能大了;

附上代码:

#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
bool cmp1(int a,int b)
{
return a<=b;
}
bool cmp2(int a,int b)
{
return a>=b;
}
int n,a[30003],f[30003],g[30003],ans;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
g[i]=INF;
for(int i=1;i<=n;i++)
{
int k=lower_bound(g+1,g+n+1,a[i],cmp1)-g;
f[i]=k;
g[k]=a[i];
ans=max(ans,f[i]);
}
for(int i=1;i<=n;i++)
g[i]=-INF;
for(int i=1;i<=n;i++)
{
int k=lower_bound(g+1,g+n+1,a[i],cmp2)-g;
f[i]=k;
g[k]=a[i];
ans=max(ans,f[i]);
}
printf("%d\n",n-ans);
return 0;
}

因为在某套模拟赛中又出现了这题原题,然后特别以为能特别轻松的拿满分来着,愉快的biabia之后,发现WA掉了!

说一下自己发现的细节:

我试着用了 挑战程序设计竞赛 那本提供的代码打了一遍,QAQ WA得特别的惨

注意的细节就是 k=lower_bound()-g;的值的问题,

感觉自己对于指针这种东西一直不是太懂,自己还是照着标准的打好了

读入的时候 从1开始读;

bool cmp(int a,int b){     return a<=b; }

for(int i=1;i<=n;i++) g[i] = INF;
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++){
int k=lower_bound(g+1,g+n+1,a[i],cmp)-g;
f[i]=k;
g[k]=a[i];
ans=max(ans,f[i]);
}

注意这里的cmp一定要定义,貌似没有定义一下会发生奇怪的事情;(不过有可能是因为我打开的方式不对)

然后就是一定不要作死按照书上的方式写!不就是多个f数组么- -

[Usaco2008 Feb]Eating Together麻烦的聚餐[最长不下降子序列]的更多相关文章

  1. Bzoj 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 二分

    1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1272  Solve ...

  2. BZOJ1609: [Usaco2008 Feb]Eating Together麻烦的聚餐

    1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 938  Solved ...

  3. BZOJ 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐( LIS )

    求LIS , 然后用 n 减去即为answer ---------------------------------------------------------------------------- ...

  4. BZOJ 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐

    1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 Description 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按F ...

  5. 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐

    1609: [Usaco2008 Feb]Eating Together麻烦的聚餐 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 1010  Solv ...

  6. [Usaco2008 Feb]Eating Together麻烦的聚餐

    Description 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想所有第3批就餐的奶牛排在队尾,队伍的前端由设定为第1批就餐的奶牛占据,中间的 ...

  7. [BZOJ1609] [Usaco2008 Feb] Eating Together麻烦的聚餐 (dp)

    Description 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想所有第3批就餐的奶牛排在队尾,队伍的前端由设定为第1批就餐的奶牛占据,中间的 ...

  8. 【BZOJ】1609: [Usaco2008 Feb]Eating Together麻烦的聚餐(dp+被坑)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1609 首先我不得不说,我被这题坑了.题目前边没有说可以不需要3种牛都有啊!!!!!!!!然后我一直在 ...

  9. 【bzoj1609】[Usaco2008 Feb]Eating Together麻烦的聚餐 dp

    题目描述 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想所有第3批就餐的奶牛排在队尾,队伍的前端由设定为第1批就餐的奶牛占据,中间的位置就归第2批 ...

随机推荐

  1. hibernate 管理 Session(单独使用session,不spring)

    Hibernate 本身提供了三个管理 Session 对象的方法 Session 对象的生命周期与本地线程绑定 Session 对象的生命周期与 JTA 事务绑定 Hibernate 托付程序管理 ...

  2. 第11章 享元模式(Flyweight Pattern)

    原文 第11章 享元模式(Flyweight Pattern) 概述:   面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时 ...

  3. oracle 数据库备份

    //创建临时表空间create temporary tablespace test_temp tempfile 'D:\oracle\data\test\test_temp.dbf' size 32m ...

  4. 网络资源(9) - TDD视频

    2014_08_26 http://v.youku.com/v_show/id_XMzI4Mzk1MjQ4.html TDD测试驱动开发

  5. LCS 小结

    转载链接:http://www.cnblogs.com/PJQOOO/p/3897745.html 第一步:先计算最长公共子序列的长度. 实现第一步: 设一个C[i][j]: 保存Xi与Yj的LCS的 ...

  6. HTML DOM的nodeName,nodeValue,nodeType介绍

    将HTML DOM中几个常用的属性做下介绍,工作中作为参考. nodeName 属性可依据节点的类型返回其名称. 元素节点的 nodeName 是标签名称 属性节点的 nodeName 是属性名称 文 ...

  7. JAVA8,SPRING,ANGULARJS对项目

    java8+spring+angularjs 项目应用 最近有写一个电子订单商务网站,使用JAVA8,SPRING,ANGULARJS对项目使用的技术和大家分享. 第一次写博客,哪有不对需要改正的请联 ...

  8. 【SSH三个框架】Hibernate第十篇基础:inverse属性具体解释

    inverse后经常用于双向1-N在相关性.它也可以在使用N-N该协会,这里,例如用双1-N联想 或两个与各部门及工作人员,两javabean没有写. 首先,我们的员工看映射文件: <?xml ...

  9. C#操作Excel初探

        近期一段时间正好在做winform导出Excel报表的问题,学习了一下C#操作Excel的一些方法(如:向Excel中插入图片:删除Excel指定sheet中的某行或某列,在Excel指定的单 ...

  10. JS工具库之Lodash

    破狼 JavaScript工具库之Lodash 2015-04-11 16:08 by 破狼, 235 阅读, 2 评论, 收藏, 编辑 你还在为JavaScript中的数据转换.匹配.查找等烦恼吗? ...