【AFOI-19】T1 数码排序

我好可怜...就这一个满分的...

原题:

题目背景

小L从虚拟世界里出来啦!

题目描述

逃出来的同时,也有一部分数码逃了出来,吵着闹着让小L帮他们排序

虚拟世界的数码都是不可见的

小L目前只会选择排序,插入排序,冒泡排序,归并排序

所以小L想问他在最坏情况下最少需要几次比较,才能使序列有序

排序的模板代码:

//归并
void msort(int l, int r) {
    if(l == r) return;
    int mid = (l + r) >> 1;
    msort(l, mid);
    msort(mid + 1, r);
    int i = l, j = mid + 1, k = l;
    while(i <= mid && j <= r)
        if(a[i] <= a[j]) ls[k++] = a[i++];
        else ls[k++] = a[j++];
    while(i <= mid) ls[k] = a[i], k++, i++;
    while(j <= r) ls[k] = a[j], k++, j++;
    for(int i = l;i <= r;i++) a[i] = ls[i];
}
//冒泡
for(int j = 1;j < n; j++)
    for(int i = 1;i <= n - j; i++)
        if(a[i] > a[i + 1])
            swap(a[i], a[i + 1]);
//插排
for(int i = 2;i <= n;i++) {
    int p = i;
    while(p > 1 && a[p] > a[p - 1]) {
        swap(a[p], a[p - 1]);
        p--;
    }
}
//选择
for(int i = 1;i < n;i++) {
    int maxx = a[i], p = i;
    for(int j = i + 1;j <= n;j++)
        if(a[j] > maxx) maxx = a[p = j];
    swap(a[i], a[p]);
}

输入格式

输入仅有一行,给定一个正整数nn,表示序列的长度

输出格式

输出最小的比较次数







容易得到递推式:

\[ f(i)=\left\{ \begin{aligned} & f(\lfloor \frac{i}{2} \rfloor)+f(\lfloor \frac{i}{2} \rfloor+1) +i-1 ,(i\ is\ odd)\\ & 2f(\lfloor \frac{i}{2}\rfloor) +i-1,(i\ is\ even)\\ \end{aligned} \right. \qquad , i \geq 2 \]
初始值\(f(1)=0\)过于显然。

#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long 
ll n;
const int N=1e7+10;
//ll f[N];
map<ll,ll> r;
ll find(ll i)
{
    if(i==1)return 0;
    if(i==2)return 1;
    if(i==3)return 3;
    if(r[i])return r[i];
    if(i&1)return r[i]=find((i>>1))+find((i>>1)+1)+i-1;
    else return r[i]=(find((i>>1))<<1)+i-1;
}
int main()
{
    cin>>n;
    cout<<find(n);
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/kion/p/11816957.html
t1