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 ;
}

最新文章

  1. android优秀Github源码整理
  2. 我在 CSDN 的小窝
  3. textview 显示html方法解析
  4. Python学习 windows下面安装Python和pip(一)
  5. Qt之QSystemTrayIcon
  6. 方便实用的jQuery checkbox复选框全选功能
  7. Mysql,SqlServer,Oracle主键自动增长的设置
  8. 各大浏览器CSS Hack收集
  9. JS响应事件整理
  10. Android 基于Netty的消息推送方案之概念和工作原理(二)
  11. 使用C#创建自定义背景色/形状的菜单栏与工具栏
  12. stm32之595(spi芯片)
  13. Windows API 之 FineFirstFile、FindNextFile
  14. stop_token.go
  15. C#工具:WPF分页
  16. PAT-Top1002. Business (35)
  17. LINUX 录制屏幕制作gif动态图工具peek
  18. MySQL之聚合数据(AVG,COUNT,MAX,MIN,SUM)
  19. VS2010自行编译OpenCV2.4.4时缺少python27_d.lib的解决方法
  20. 使用 yield 减少内存消耗

热门文章

  1. Bootstrap 12 栅格系统
  2. LeetCode(59)SPiral Matrix II
  3. LeetCode(46)Permutations
  4. python网络编程01
  5. jmap Unable to open socket file解决
  6. PowerShell Tools for Visual Studio 2015
  7. CC3200 TI 笔记
  8. 九度oj 题目1064:反序数
  9. noip模拟赛 卖书
  10. POJ 1988相对偏移