CSU 1807: 最长上升子序列~ 分类讨论
2016-09-06 11:30
176 查看
1807: 最长上升子序列~
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 138 Solved: 17
[Submit][Status][Web Board]
Description
Bobo 在 ICPCCamp 学会了解决最长上升子序列问题后得到了一个长度为 n 的数列 p1,p2,…,pn.Bobo 想用 1,2,…,n 来替换其中值为 0 的元素,使得 p1,p2,…,pn 互不相同(即 p1,p2,…,pn 是 {1,2,…,n} 的排列)。
现在 Bobo 想知道,替换后最长上升子序列的长度恰好为 (n-1) 数列的数量。
Input
输入包含不超过 300 组数据,其中不超过 20 组的 n 超过 100.每组数据的第一行包含一个整数 n (1≤n≤105).
第二行包含 n 个整数p1,p2,…,pn (0≤pi≤n).
保证p1,p2,…,pn中非 0 的元素互不相同。
Output
对于每组数据,输出一个整数表示要求的值。Sample Input
3 0 0 0 4 0 0 0 0 5 1 0 0 4 5
Sample Output
4 9 1
HINT
Source
湖南省第十二届大学生计算机程序设计竞赛[Submit][Status][Web Board]
分析:就是大分类讨论,考虑偏移
#include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; const int N = 1e5 + 5; const double eps = 1e-9; const double INF = 1e12; int n,a ,b ,m ; void solve3(int id){ memset(b,0,sizeof(b)); b[id] = a[id];int cnt=0; for(int i=1;i<=n;++i){ if(i==id)continue; ++cnt;if(cnt==a[id])++cnt; b[i]=cnt; } for(int i=1;i<=n;++i) if(a[i]&&a[i]!=b[i]){ puts("0"); return; } puts("1"); } void solve1(int id){ if(a[id+1]==id){ for(int i=1;i<=n;++i){ b[i]=i; } swap(b[id],b[id+1]); for(int i=1;i<=n;++i){ if(a[i]&&a[i]!=b[i]){ puts("0");return; } } puts("1"); return; } int r=id,flag=0; for(int i=id+1;i<=n;++i){ if(a[i] == 0)continue; if(i!=a[i]){ if(!flag&&a[i]==i+1)r=i; else{ puts("0"); return; } } if(i==a[i])flag=1; } int t1 = 0,t2 = 0; for(int i= id-1;i&&a[i]==0;--i)++t1; for(int i=r+1;i<=n&&a[i]==0;++i)++t2; LL ret = 1ll*(t1+1)*t2; printf("%lld\n",ret); } void solve2(int id){ if(a[id-1]==id){ for(int i=1;i<=n;++i){ b[i]=i; } swap(b[id],b[id-1]); for(int i=1;i<=n;++i){ if(a[i]&&a[i]!=b[i]){ puts("0");return; } } puts("1"); return; } int r=id,flag=0; for(int i=id+1;i<=n;++i){ if(a[i]==0)continue; if(i!=a[i]){ if(!flag&&a[i]==i-1)r=i; else{ puts("0"); return; } } if(i==a[i])flag=1; } int t1 = 0,t2 = 0; for(int i=id-1;i&&a[i]==0;--i)++t1; for(int i=r+1;i<=n&&a[i]==0;++i)++t2; LL ret = 1ll*(t2+1)*t1; printf("%lld\n",ret); } int main(){ while(~scanf("%d",&n)){ memset(m,-1,sizeof(m)); for(int i=1;i<=n;++i)scanf("%d",&a[i]),m[a[i]]=i; bool flag = false; for(int i=1;i<=n;++i){ if(a[i]&&(a[i]-i>1||i-a[i]>1)){ solve3(i); flag = true; break; } } if(flag)continue; for(int i=1;i<=n;++i){ if(a[i]==0||a[i]==i)continue; if(a[i]-i==1)solve1(i); else if(i-a[i]==1)solve2(i); flag = true; break; } if(flag)continue; int cnt=0;LL ret=0; for(int i=1;i<=n;++i){ if(a[i]==0)++cnt; else if(cnt){ ret+=1ll*(cnt-1)*(cnt-1); cnt=0; } } if(cnt)ret+=1ll*(cnt-1)*(cnt-1); printf("%lld\n",ret); } return 0; }
View Code
相关文章推荐
- Vuejs第十篇之vuejs父子组件通信
- Unity3D开发为什么C#语言学习叫苦连连
- 进程保活
- Linux 管理
- 算法竞赛入门第七章:竞赛选讲(Uva12325,Uva1603)
- 工作期间常用的linux命令
- 如何创建SSH Keys(Git)
- win10杜比音效安装教程以及资源
- #pragma 预处理指令详解
- 为什么不应该使用ZooKeeper做服务发现
- 机器学习/深度学习/自然语言处理学习路线
- 详解Redis用链表实现消息队列
- 区分:P问题、NP问题、NPC问题、NP-hard问题(自己收藏,转载)
- Facebook Surround 360 环境配置指南
- 顶点着色器-经过的空间变换
- art template前端模板引擎
- ML数学知识琐碎
- postgresql启动、状态查看、关闭
- Codeforces 510 E Fox And Dinner【预处理素数+建图+最大流Dinic】好题
- NSTextAttachment实现图文混排