这道题虽然是noip的题,但还是很能反映你思维水平的、

说出来二分图、黑白染色对于一个oier来说肯定不陌生,有的人很快就能说出做法,写出程序。

但是一出成题怎么就不会了呢?

其实主要失误在于 我是站在选A、B的角度思考问题的,但实际上,如果思路足够清晰,还是能回到互斥的角度的

因为如果站在选A选B的角度上,能影响当前决策的实际上有3个不同的因素,1是出现顺序,这好办,扫过去就行。2是当前栈中元素的影响(这实际上是有后效性的,因为后面的数也会对当前决策造成影响:后面小数卡大数,导致空间被浪费,同时贪心是错的:不信用7251463 试试、),3是当前数消不消除的影响。。(这比较坑,但如果从第2点已经看出后效性的话已经证实至少不是1个dp解决问题的题了)

这时候应该敏锐地发现,这种后效性是由空间消耗造成的,因为我们的贪心实际上维护的是一个尽量装A的序列,如果是跳着从大到小的序列,那对A的空间利用极低。

(ps:最讨厌分析中的“不妨”,这俩字没有任何意义,,解题的每一步都应该在题目中有根据的,用“不妨”蒙混过关对自己的思维并没有太大的帮助)

当然,对于能处理的情况,我们首选A列,那么我们应该还是用dp来维护,但并不完成划分A、B工作,只是把能放在一个栈里的区间求出来,

然后由于非A即B,就需要利用黑白染色的互斥原理,进行遍历。

总结:这题分析不出来,主要是思路受尽量选A的条件制约,抓住贪心放不开,认为前几个都应该放A里,且忽略了可行性这一重要因素,可行性是受尽量选A影响的。

应建立在可行性上尽量选A,而不是在尽量选A中实现可行性。

补一下,个人感觉第一步的dp也挺难的、

可以从小的数据入手:

1 2 3     :肯定可以单栈;                               1 3 2   :肯定可以单栈                          2 1 3    肯定可以单栈                  2 3 1:肯定不可以单栈(需要分开,且一定是2和3分开)

3 1 2   :肯定可以单栈                                3 2 1     肯定可以单栈

这样就考虑了退出的情况,强行装,为什么不会出现不可行的情况?因为不可装只和弹出、装入有关,现在dp考虑了出栈,如果在加上弹出的情况,A装不下了,那就是无论如何也装不下了,只能另寻栈。

#include<iostream>
#include<cstdio>
using namespace std;
int n,woc,a[99999],i,j,l,stacka[99998],stackb[99999],topa,topb,tu[1999][1999],sta[1999],ru[1999];
bool keyi,zou[1999];
void dfs(int now)
{if(keyi==0)return ;for(int i=1;i<=n;i++){   if(zou[i])continue;if(tu[i][now]||tu[now][i]){if((sta[now]==1&&sta[i]==1)||(sta[now]==2&&sta[i]==2)){keyi=0;   return ;          }if(sta[now]==1&&sta[i]==-1)sta[i]=2;if(sta[now]==2&&sta[i]==-1)sta[i]=1;zou[i]=1;dfs(i);        }       }
}
int main()
{scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&a[i]);for(i=1;i<=n;i++)for(j=i+1;j<=n;j++){if(a[i]>a[j])continue;for(l=j+1;l<=n;l++){if(a[l]<a[i]&&a[l]<a[j]){tu[j][i]=1;ru[i]++;ru[j]++;}}}for(i=1;i<=n;i++)if(ru[i]>0)sta[i]=-1;else sta[i]=1;keyi=1;for(i=1;i<=n;i++){if(ru[i]==1&&sta[i]==-1){sta[i]=1;zou[i]=1;dfs(i);}}for(i=1;i<=n;i++)if(sta[i]==-1)keyi=0;if(!keyi){cout<<0;return 0;}stacka[0]=99999;stackb[0]=99999;woc=1;for(i=1;i<=n;i++){if(sta[i]==1){while(stacka[topa]<a[i]){if(stacka[topa]==woc){topa--;printf("b ");          }else{   topb--;printf("d "); }woc++;               }printf("a ");stacka[++topa]=a[i];}else {while(stacka[topa]==woc){topa--;printf("b ");woc++;}while(stackb[topb]<a[i]){if(stacka[topa]==woc){   topa--;printf("b ");           }else{   topb--;printf("d "); }woc++;               }stackb[++topb]=a[i];printf("c "); } } for(i=woc;i<=n;i++){if(stacka[topa]==i){printf("b ");--topa;         }else {printf("d ");--topb;   }}
}

=======================================2017.8.21==========================================

我们应该学会简化一些问题,来为更复杂的问题打开思路

如发现直接做两个的很难搞,所以我们就先考虑一个的

一个的似乎也不好搞,于是我们可以尝试操作一些数来找操作上的规律

我们注意到,,我们首先知道,它只与前面的数有关,其次知道几组不能单栈的数列

然后我们判断一个数已经不能被排了,看的是栈顶的数的相对大小,而不是一个值

所以我们可以推广到所有数,所以也就会得到   数的大小关系   的信号

所以我们就可以通过大小关系,递推,得到dp

然后到双栈的情况,我们可以先用一个栈装,然后再用另一个栈,因为空栈显然比放了几个数的栈限制更小

双栈的时候就可以考虑经典的分配问题,通过互斥进行分配,判定可行性

要学会小->大  数值->关系的推广角度

2017.3.3 双栈排序 失败总结相关推荐

  1. P1155 双栈排序(二分图的染色判断+链式前向星)

    P1155 双栈排序 让字典序最小,当然尽量进S1 那什么时候必须进S2呢? a[i]和a[j] 不能压入同一个栈⇔存在一个k,使得i<j<k且a[k]<a[i]<a[j] 因 ...

  2. P1155 双栈排序(二分图染色)

    P1155 双栈排序(二分图染色) 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一 ...

  3. AC日记——双栈排序 洛谷 P1155

    双栈排序 思路: 二分图染+模拟: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 #define ...

  4. NOIP2008 双栈排序

    https://www.luogu.org/problem/show?pid=1155 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输 ...

  5. 【每日一题】8月7日题目精讲—双栈排序

    来源:牛客网 文章目录 题目描述 题意: 题解: 代码: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言262144K 64bit IO Format: %l ...

  6. [大牛就是牛]双栈排序

    [题目描述] Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈 ...

  7. P1155 双栈排序

    P1155 双栈排序 题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S ...

  8. 洛谷——P1155 双栈排序

    题目描述 Tom最近在研究一个有趣的排序问题.如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序. 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1 ...

  9. 虚拟化构建二分图(BZOJ2080 题解+浅谈几道双栈排序思想的题)

    虚拟化构建二分图 ------BZOJ2080 题解+浅谈几道双栈排序思想的题 本题的题解在最下面↓↓↓ 不得不说,第一次接触类似于双栈排序的这种题,是在BZOJ的五月月赛上. [BZOJ4881][ ...

最新文章

  1. 如何使用C++ Builder 6.0连接Access数据库
  2. [转]几句不可不看的经典人生语句
  3. Android 告急!
  4. C++代码片段(五)tuple的实现
  5. 253B. Physics Practical
  6. codeforces 344A-C语言解题报告
  7. css怎样定义div大小,css如何设置div大小
  8. 解决org.springframework.web.multipart.MaxUploadSizeExceededException报错问题
  9. CSS简介和CSS选择器
  10. 老程序员被裁员,面试半年未果,同行:都四十了还是码农,怪谁?
  11. 安卓输入法 车机版_搜狗输入法车机下载安装-搜狗输入法车载版下载v10.10.1 安卓版-单机手游网...
  12. Excel的25个知识~边看边操作
  13. 银行测试(7)-支付测试
  14. 卫星天线如何接受CCTV-5nbsp;CCTV-6
  15. Arrays中的asList注意的点以及解决方案
  16. 你是否真的适合软件测试行业?
  17. Python生成 gif 动图
  18. EasyExcel 单元格背景颜色、字体颜色使用2种设置颜色方法(IndexedColors中定义的颜色,自定义RGB颜色)实现
  19. 妹子面试阿里,面试官竟问她有没有男朋友?面试真题「PDF分享
  20. 人生苦短我用Python 五:ERROR: No matching distribution found for REfo==0.13

热门文章

  1. 红橙Darren视频笔记 仿汽车之家 可拖动列表
  2. 最小公倍数一些性质定理及证明
  3. OpenCV+Python(官方中文版翻译)
  4. SQL Server where语句使用举例
  5. @configurationproperties注解的使用_徒手使用SpringBoot自定义Starter启动器
  6. flask-mail异步发送邮件_Python爬虫系列:用邮件来通知爬虫异常状况
  7. 找出数组中不重复的一个数
  8. 大华的支持rtmp推流吗_RTSP安防摄像机(海康大华宇视等)如何推送到RTMP流媒体服务器进行直播...
  9. python模拟多线程http请求_用python实现自己的http服务器——多进程、多线程、协程、单进程非堵塞版、epoll版...
  10. python代码片段_Python 常用代码片段