給出乙個數列,每次可以把乙個單調遞減的序列反過來,求最少要反多少次才能使這個序列單調遞增。 in
put inp
ut
6
5 3 2 1 6 4
ou
tput
o ut
pu
t
3
對於乙個數列,我們可以先按照題目所說的將單調遞減的數列取反。
就變成這時候,每個曾經單調遞減的數列就單調遞增了,每個區間內的數列肯定滿足單調遞增,所以剩下的肯定是兩個區間之間的數字不滿足單調遞增。
那麼很容易發現,剩餘需要取反的數字個數一定是現在數列逆序對的個數,所以,再用歸併排序求出逆序對的個數即可。
#include
#include
using
namespace
std;
long
long n,a[100011],b[100011],sum,i,j;
void make(long
long l,long
long mid,long
long r) //合併
else
if (p2>r)
else
if (a[p1]>a[p2])
else
}for (long
long i=l;i<=r;i++) //重新賦值
a[i]=b[i];
}void sorts(long
long l,long
long r) //拆分
}int main()
i=j=j+1;
}sorts(1,n); //求逆序對
printf("%lld\n",sum);
return
0;}
休息 歸併排序 模擬
給出乙個數列,每次可以把乙個單調遞減的序列反過來,求最少要反多少次才能使這個序列單調遞增。in put role presentation inp utin put6 5 3 2 1 6 4ou tput role presentation out puto utpu t3對於乙個數列,我們可以先按...
逆序對 模擬歸併排序
逆序數的定義 如果 i j 且a i a j 則a i 和a j 即為逆序數對 給一列數,求它的逆序對數,即有多少個有序對 i.j 使得i在歸併排序的基礎上記上了乙個逆序對個數的統計 ans mid i 1 void merge int arr,int left,int mid,int right ...
歸併排序(2 路歸併排序)
遞迴寫法 include define maxn 100 void merge int a,int l1,int r1,int l2,int r2 將陣列a的區間 l1,r1 和區間 l2,r2 合併為乙個有序區間 else while i r1 while j r2 for int i 0 i非遞...