题目链接:https://ac.nowcoder.com/acm/contest/5668/E
题意:给一个序列s,在这个序列里面找出两种不同序列的两两匹配,使得所有两两匹配的差的和最小,输出这个和。
关键词:找规律与动态规划。
做题思路:硬规律,害,推断出长度是4与6的划分(推不出来就GG了,还是要多看看多积累),然后再用动态规划。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
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;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
dp[i]=inf64,cin>>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]);
}
cout<<dp[n]<<endl;
}
}
京公网安备 11010502036488号