Consider if you can determine the location of each shoe to the final exchange, then the answer is easy to calculate
Specifically, if the original location for the $ i $ shoes to be exchanged to $ pos [i] $ then the number is the final answer in reverse order of $ pos $
If you do not know can go write NOIP2013 match line up my explanations have proof about this
Consider how to determine the optimal solution, easy to think of each of the shoes are shoes find the closest match, this is right
Proof (Reference blog ):
A final set of adjacent two pairs of shoes $ (a, b) (c, d) $, where $ (a, b) $ represents the initial position of the shoes is $ a, b $, $ (c, d ) $ Similarly, we may assume $ a <c $,
If $ a <b <c <d $ then $ (a, b) (c, d) $ Number reverse the generation of $ 0 $, $ (c, d) (a, b) $ Number reverse the generation of $ 4 $
If $ a <c <b <d $ then $ (a, b) (c, d) $ Number reverse the generation of $ 1 $, $ (c, d) (a, b) $ Number reverse the generation of $ 3 $
If $ a <c <d <b $ then $ (a, b) (c, a) $ Number reverse the generation of $ 2 $, $ (c, d) (a, b) $ Number reverse the generation of $ 2 $
Therefore, if the adjacent pairs of shoes for a $ (c, d) (a, b) $, and $ a <c $, so they will not exchange scheme is more inferior
So every greedy recently selected shoes to match specific implementation look at the code
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<vector> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=4e5+7; int n,n2,a[N],pos[N]; ll ans; bool vis[N]; vector <int> L[N],R[N];//桶 int t[N]; inline void add(int x,int v) { while(x<=n2) t[x]+=v,x+=x&-x; } inline int ask(int x) { int res=0; while(x) res+=t[x],x-=x&-x; return res; } int main() { n=read(); n2=n*2; for(int i=1;i<=n2;i++) { a[i]=read(); a[i]<0 ? L[-a[i]].push_back(i) : R[a[i]].push_back(i); } for(int i=1;i<=n;i++) { int len=L[i].size(); for(int j=0;j<len;j++) { pos[L[i][j]]=R[i][j]; pos[R[i][j]]=L[i][j]; ans+=L[i][j]>R[i][j];//注意细节 } } for(int i=1;i<=n2;i++) add(i,1); for(int i=1;i<=n2;i++) { if(VIS [I]) Continue ; the Add (I, - . 1 ); the Add (POS [I], - . 1 ); VIS [I] = VIS [POS [I]] = . 1 ; ANS + = ASK (POS [I ]); // request after it is smaller than or equal to its number } // Fenwick tree maintenance number reverse the printf ( " % LLD \ n- " , ANS); return 0 ; }