Trees ——CodeForces - 58C 题解

On Bertown’s main street n trees are growing, the tree number i has the height of ai meters (1 ≤ i ≤ n). By the arrival of the President of Berland these trees were decided to be changed so that their heights formed a beautiful sequence. This means that the heights of trees on ends (the 1st one and the n-th one) should be equal to each other, the heights of the 2-nd and the (n - 1)-th tree must also be equal to each other, at that the height of the 2-nd tree should be larger than the height of the first tree by 1, and so on. In other words, the heights of the trees, standing at equal distance from the edge (of one end of the sequence) must be equal to each other, and with the increasing of the distance from the edge by 1 the tree height must also increase by 1. For example, the sequences “2 3 4 5 5 4 3 2” and “1 2 3 2 1” are beautiful, and ‘1 3 3 1” and “1 2 3 1” are not.

Changing the height of a tree is a very expensive operation, using advanced technologies invented by Berland scientists. In one operation you can choose any tree and change its height to any number, either increase or decrease. Note that even after the change the height should remain a positive integer, i. e, it can’t be less than or equal to zero. Identify the smallest number of changes of the trees’ height needed for the sequence of their heights to become beautiful.

Input
The first line contains integer n (1 ≤ n ≤ 105) which is the number of trees. The second line contains integers ai (1 ≤ ai ≤ 105) which are the heights of the trees.

Output
Print a single number which is the minimal number of trees whose heights will have to be changed for the sequence to become beautiful.

Example
Input
3
2 2 2
Output
1
Input
4
1 2 2 1
Output
0


题意大概就是把队列修改成对称且连续递增1的,求需要修改的最小数目,做法就是枚举固定一个点,搜索以这个点为基准修改成目标状态的不需要修改的数量,并且这些不用修改的点以后枚举就可以跳过了(因为它们属于同一个免修改块),因此加一个bool数组记录,枚举搜索一边就可以找到最大的免修改值,用n减去免修改值就是答案了。

#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<cmath>
#include<stdio.h>
using namespace std;
int n;
int a[100005];
bool v[100005];
int main(){
    //total-freenum,find the max of freenum
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    if(n==1){printf("0");return 0;}
    int ans=n;
    int maxfree=0;
    for(int i=1;i<=n/2;i++){
        if(v[i])continue;
        v[i]=1;
        if(a[i]<i)continue;
        int maxn=0;
        for(int j=i;j<=n/2;j++){
            if(a[j]-a[i]==j-i){
                v[j]=1;
                maxn++;
            }
            if(a[n-j+1]-a[i]==j-i){
                v[n-j+1]=1;
                maxn++;
            }
        }
        if(n%2==1){if(a[n/2+1]-a[i]==n/2+1-i){maxn++;}}
        maxfree=max(maxfree,maxn);
    }
    int k=n/2;
    if(n%2==1)k++;
    for(int i=n;i>k;i--){
        if(v[i])continue;
        v[i]=1;
        if(a[i]<n-i+1)continue;
        int maxn=0;
        for(int j=i;j>k;j--){
            if(a[j]-a[i]==i-j){
                v[j]=1;
                maxn++;
            }
            if(a[n-j+1]-a[i]==i-j){
                v[n-j+1]=1;
                maxn++;
            }
        }
        if(n%2==1){if(a[n/2+1]-a[i]==i-(n/2+1)){maxn++;}}
    maxfree=max(maxfree,maxn);
    }


    printf("%d",ans-maxfree);
    return 0;
}

。。。似乎有更快的做法= =

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值