Stay Hungry,Stay Foolish!

F - Permutation Distance -- ATCODER

F - Permutation Distance

https://atcoder.jp/contests/abc283/tasks/abc283_f

 

思路

最小生成树法:

https://zhuanlan.zhihu.com/p/595421879

 

动态缩减查找距离法

朴素思维: 如果按照Di定义,对于每个i,都需要计算n-1次进行比较,然后取得最小值

朴素思维中,有很多比较是不必要的。

从另外一个角度看对于每个i, 考虑其能够搜索的距离空间,

对于当前已经查找的最小Di, 决定了其当前的搜索空间的上届和下界, 对于上届和下界以外的点, PiPj+ij∣ 是大于当前最小Di的,所以不要考虑。

参考 -- 动态缩减查找距离

https://atcoder.jp/contests/abc283/submissions/37706607

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
ll a[200005], n;
signed main(){
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++){
        ll gt_i;//表示目前找到的Di最小值 
        gt_i = n * 2;
        for(int k/*表示i与j的距离*/ = 1; k <= gt_i; k++){// 若k>gt_i,则|p[i]-p[j]|+|i-j|=|p[i]-p[j]|+k>k>gt_i,即 |p[i]-p[j]|+|i-j|一定大于gt_i,不可能成为最小值。不用考虑。 
            if(i > k) gt_i = min(gt_i, abs(a[i] - a[i - k]) + k);//i前面k个数 
            if(i + k <= n) gt_i = min(gt_i, abs(a[i] - a[i + k]) + k);//i后面k个数 
        }
        cout << gt_i << ' ';
    }
    return 0;
}

 

posted @ 2023-01-03 12:20  lightsong  阅读(39)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel