1807: 最长上升子序列~

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 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 + ;
const double eps = 1e-;
const double INF = 1e12;
int n,a[N],b[N],m[N];
void solve3(int id){
memset(b,,sizeof(b));
b[id] = a[id];int cnt=;
for(int i=;i<=n;++i){
if(i==id)continue;
++cnt;if(cnt==a[id])++cnt;
b[i]=cnt;
}
for(int i=;i<=n;++i)
if(a[i]&&a[i]!=b[i]){
puts("");
return;
}
puts("");
}
void solve1(int id){
if(a[id+]==id){
for(int i=;i<=n;++i){
b[i]=i;
}
swap(b[id],b[id+]);
for(int i=;i<=n;++i){
if(a[i]&&a[i]!=b[i]){
puts("");return;
}
}
puts("");
return;
}
int r=id,flag=;
for(int i=id+;i<=n;++i){
if(a[i] == )continue;
if(i!=a[i]){
if(!flag&&a[i]==i+)r=i;
else{
puts("");
return;
}
}
if(i==a[i])flag=;
}
int t1 = ,t2 = ;
for(int i= id-;i&&a[i]==;--i)++t1;
for(int i=r+;i<=n&&a[i]==;++i)++t2;
LL ret = 1ll*(t1+)*t2;
printf("%lld\n",ret);
}
void solve2(int id){
if(a[id-]==id){
for(int i=;i<=n;++i){
b[i]=i;
}
swap(b[id],b[id-]);
for(int i=;i<=n;++i){
if(a[i]&&a[i]!=b[i]){
puts("");return;
}
}
puts("");
return;
}
int r=id,flag=;
for(int i=id+;i<=n;++i){
if(a[i]==)continue;
if(i!=a[i]){
if(!flag&&a[i]==i-)r=i;
else{
puts("");
return;
}
}
if(i==a[i])flag=;
}
int t1 = ,t2 = ;
for(int i=id-;i&&a[i]==;--i)++t1;
for(int i=r+;i<=n&&a[i]==;++i)++t2;
LL ret = 1ll*(t2+)*t1;
printf("%lld\n",ret);
}
int main(){
while(~scanf("%d",&n)){
memset(m,-,sizeof(m));
for(int i=;i<=n;++i)scanf("%d",&a[i]),m[a[i]]=i;
bool flag = false;
for(int i=;i<=n;++i){
if(a[i]&&(a[i]-i>||i-a[i]>)){
solve3(i);
flag = true;
break;
}
}
if(flag)continue;
for(int i=;i<=n;++i){
if(a[i]==||a[i]==i)continue;
if(a[i]-i==)solve1(i);
else if(i-a[i]==)solve2(i);
flag = true;
break;
}
if(flag)continue;
int cnt=;LL ret=;
for(int i=;i<=n;++i){
if(a[i]==)++cnt;
else if(cnt){
ret+=1ll*(cnt-)*(cnt-);
cnt=;
}
}
if(cnt)ret+=1ll*(cnt-)*(cnt-);
printf("%lld\n",ret);
}
return ;
}

CSU 1807: 最长上升子序列~ 分类讨论的更多相关文章

  1. 【模拟】CSU 1807 最长上升子序列~ (2016湖南省第十二届大学生计算机程序设计竞赛)

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1807 题目大意: 给你一个长度为N(N<=105)的数列,数列中的0可以被其他数 ...

  2. CSU 1225 最长上升子序列并记录其个数

    ;j<i;j++){ if(h[i] > h[j]){ ) cnt[i]+=cnt[j]; ) len[i] = len[j] + , cnt[i] = cnt[j]; } //身高相同的 ...

  3. [csu/coj 1078]多个序列的最长公共子序列

    题意:给n个序列,同一个序列里面元素互不相同,求它们的最长公共子序列. 思路:任取一个序列,对于这个序列里面的两个数ai,aj(i<j),如果对于其它每一个序列,都出现过ai,aj,且ai在aj ...

  4. 经典递归问题:0,1背包问题 kmp 用遗传算法来解背包问题,hash表,位图法搜索,最长公共子序列

    0,1背包问题:我写笔记风格就是想到哪里写哪里,有很多是旧的也没删除,代码内部可能有很多重复的东西,但是保证能运行出最后效果 '''学点高大上的遗传算法''' '''首先是Np问题的定义: npc:多 ...

  5. 最长上升子序列(LIS)模板

    最长递增(上升)子序列问题:在一列数中寻找一些数,这些数满足:任意两个数a[i]和a[j],若i<j,必有a[i]<a[j],这样最长的子序列称为最长递增(上升)子序列. 考虑两个数a[x ...

  6. 【动态规划】拦截导弹_dilworth定理_最长递增子序列

    问题 K: [动态规划]拦截导弹 时间限制: 1 Sec  内存限制: 256 MB提交: 39  解决: 10[提交][状态][讨论版] 题目描述 张琪曼:“老师,修罗场是什么?” 墨老师:“修罗是 ...

  7. 算法导论-动态规划(最长公共子序列问题LCS)-C++实现

    首先定义一个给定序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果,其形式化定义如下:给定一个序列X = <x1,x2 ,..., xm>,另一个序列Z =<z1,z2  ...

  8. 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...

  9. DP:LCS(最长公共子串、最长公共子序列)

    1. 两者区别 约定:在本文中用 LCStr 表示最长公共子串(Longest Common Substring),LCSeq 表示最长公共子序列(Longest Common Subsequence ...

随机推荐

  1. MySQL主从配置详解

    一.mysql主从原理 1. 基本介绍 MySQL 内建的复制功能是构建大型,高性能应用程序的基础.将 MySQL 的 数亿分布到到多个系统上去,这种分步的机制,是通过将 MySQL 的某一台主机的数 ...

  2. nginx配置location项的URL匹配规则

    Localtion URL的正则匹配规则 示例 location / { try_files $uri @apache; } #所有的路径都是/开头,表示匹配所有 location @apache { ...

  3. CSRF之Ajax请求

    A:Ajax提交数据是,携带的CSRF在data中: <form method="POST" action="/csrf.html"> {% csr ...

  4. json pickle shelve hashlib collections time

    import json # Json模块提供了四个功能:dumps.dump.loads.load dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = js ...

  5. uva 1592 Database (STL)

    题意: 给出n行m列共n*m个字符串,问有没有在不同行r1,r2,有不同列c1,c2相同.即(r1,c1) = (r2,c1);(r1,c2) = (r2,c2); 如 2 3 123,456,789 ...

  6. Python+selenium下拉菜单选项

    案例:在我要自学网登录页面选择要保留的时间 具体页面如图所示: 使用前端工具查看部分页面代码: <select class="loinp" name="Cookie ...

  7. jQuery_计算器实例

    知识点: fadeIn()---计算器界面载入淡入效果 hover()---鼠标移入移出某个元素时触发的事件 click()---鼠标单击事件 css()---对元素样式的操作 val()---获取表 ...

  8. codeforces 361A

    //这题看着吓人,为何这么水 #include<stdio.h> int main() {  int n,m,i,j;  while(scanf("%d%d",& ...

  9. 关于struct函数以及重载

    1,关于其函数的应用 我们从这里可以看出,void,int,Node,这三种类型,都是可以定义的. 2,重载的方式 如何重载比较符号 这里的比较重载就是小于号,如果前者x比后者x小就返回真 否则返回假 ...

  10. next_permitation

    了解一个C++ STL的函数 next_permitation 可用于生成全排列 如下例子 #include <iostream> #include <stdio.h> #in ...