2020牛客暑期多校訓練營(第三場)E Two Matchings
阿新 • • 發佈:2020-07-20
2020牛客暑期多校訓練營(第三場)E Two Matchings
題解:
這個題目我覺得也有點難,主要是難以想到就dp 4和6。
首先 \(p_i!=i \,\,and \,\,p_{pi}=i\) 可得如果 \(p_x=i\) ,那麼 \(p_i=x\)
所以再來看這個要求的式子:\((\sum_{i=1}^{n}abs(a_i-a_{pi}))/2\)
可以知道一定存在 \(a_i=a_{pi}\) 和 \(a_{pi}-a_i\) ,把這個2消去,所以最後就變成了對於這n個數,找到 \(\frac{n}{2}\) 對數之差最小,要找到兩個這樣的,並且這兩個不能有任意一對相同。
最後就是觀察出來,要麼拆成6,要麼拆成4,最後dp一下。
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f #define debug(x) printf("debug:%s=%lld\n",#x,x); //#define debug(x) cout << #x << ": " << x << endl using namespace std; const int maxn = 2e6+10; typedef long long ll; ll pre1[maxn],pre2[maxn]; ll dp[maxn],a[maxn]; int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) dp[i]=inf64,scanf("%lld",&a[i]); sort(a+1,a+1+n); dp[0]=0; for(int i=1;i<=n;i+=2) dp[0]+=a[i+1]-a[i]; for(int i=4;i<=n;i++) pre1[i]=a[i]+a[i-1]-a[i-2]-a[i-3]; for(int i=6;i<=n;i++) pre2[i]=a[i]+a[i-1]+a[i-3]-a[i-2]-a[i-4]-a[i-5]; for(int i=4;i<=n;i++){ if(i>=4) dp[i]=min(dp[i],dp[i-4]+pre1[i]); if(i>=6) dp[i]=min(dp[i],dp[i-6]+pre2[i]); } printf("%lld\n",dp[n]); } }