Vijos 1925 老爷爷与老奶奶
来源:互联网 发布:90年代网络歌曲 编辑:程序博客网 时间:2024/05/05 00:39
【题意】给定长度为n的数列,每次将最后的元素调到最前,问最少多少次能成为不下降序列(2<=n<=100000)
【分析】
①设原数列为A,A的操作具有周期性,因为调了n次回到原型
②构造数列B,使得B的长度为n+n-1,对于1<=i<=n,B[i]=A[i],对于n<i<2n,B[i]=A[i-n],例如:
A数列为3 4 5 1 2
B数列为 3 4 5 1 2 3 4 5 1,
现在的目标就是在A,B间建立联系
③A数列操作后与B数列长度为n的连续子序列一一对应
④若B数列以i开头的长度为n的连续子序列为不下降子序列,则A数列最少进行(n-i+1)%n次操作后为不下降子序列
⑤所以除非B的开头i=1,答案为0,否则B的开头越后,答案越小
⑥这样就可以使用贪心算法,从头到尾扫一遍,找连续的不下降子序列,注意去不去等于的问题。
设开头为j,结尾为k,则其中存在k-n-j+1个连续子序列,注意不是1个,因为相邻两个数可以相同,例如:
A:1 1 1 1 1
B:1 1 1 1 1 1 1 1 1
[1] 当j=1时,直接返回答案0
[2] 当j^1时,因为满足⑤的性质,所以取当前最优答案n-(k-n+1)+1=n+n-k次操作
然后继续扫,因为可能还有更优的,我第一次就栽在这里;
最终答案就是最后一次连续子序列的答案~~~
【代码】
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int N=100001;
int n,a[N<<1],t,res=-1;
void init(void)
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<n;i++) a[n+i]=a[i];
n=(t=n)*2-1;
}
void work(void)
{
int j;
for (int i=1;i<=n;i++)
{
for (j=i;j<n&&a[j]<=a[j+1];j++);
if (j-i+1>=t) if (i==1) {res=0;break;} else res=t+t-j;
i=j;
}
printf("%d\n",res);
}
int main(void)
{
init();
work();
return 0;
}
【小结】
①序列的周期性问题,通常用轮回构造,例如环形DP也是差不多的
②这种求连续什么的贪心线性算法要熟悉,很多时候在二分法和其他情况也会用到
③注意不下降子序列与上升子序列的区别
- Vijos 1925 老爷爷与老奶奶
- 白芳礼【敬重的老爷爷】
- 余光中老爷爷走好!!!
- 送老奶奶回家
- 扶老奶奶过马路
- Vijos P1836HYS与七夕节大作战
- Vijos 1696-数与连分数【模拟】
- Vijos 1696题:数与连分数
- Vijos P1696 数与连分数【连分数】
- HYS与七夕节大作战 vijos
- 80后回忆-老奶奶拜佛
- 蓝桥杯-扶老奶奶过街
- 蓝桥杯 扶老奶奶过街
- 蓝桥杯 扶老奶奶过街
- Vijos P1836 HYS与七夕节大作战
- Vijos 1836题:HYS与七夕节大作战
- 可是小朋友不顾老奶奶说的台词话
- 蓝桥杯 扶老奶奶过街 (逻辑推理)
- 针对效率的自我反思
- 杭电-2071 Max Num
- Vijos 1922 木姑娘的生日
- Vijos 1919 最有活力的鲜花
- Vijos 1924 幸福的二次相遇
- Vijos 1925 老爷爷与老奶奶
- Vijos 1932 重要的誓言
- 杭电-2051 Bitset
- NOIP 2014 提高组 Day2 T2 寻找道路
- 四,从头到尾在myeclipse中的java开发环境搭建之SQLServer2000数据库的安装
- 杭电-2099 整除的尾数
- NOIP 2014 提高组 Day2 T1 无线网路发射器选址
- POJ 1001 Exponentiation
- POJ 1002 487-3279