2020牛客暑期多校训练营 (第三场)E Two Matchings【排序后按照 4或6个分成1块的选择 来dp】

题目链接

这个题我搞出来一个贪心,看起来对的一批,一选是最小,然后二选也是最小,但是不能这么搞的。因为一选最小不能保证一选+二选的结果也是最小的。然后比完赛发现师兄们一开始也是这样,搞出来假贪心,还觉得正确的一批。
先对a数组sort一下,就是从a[1]到a[n]递增。
头尾取法:对于最大是必为正数的,最小是必为负数的,那么中间错开来就是说ans=2a[n]-2[1];
为了得出这个期望,应该是按照连续两个a,或者是连续4个a进行分块,然后使用这个头尾取法。
当n=16;
决策如果是2分块:16 15进行万能取法,得到2a16-2a15
决策如果是4分块:16 15 14 13进行万能取法,得到2a16-2a13
然后开始dp就行了。

我打了个假算法,然后队友一针见血说了按4 6分块。

太草了,我该反省,为什么我想不到按照4 6 分块,他想到了。
附上队友的代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const double eps=1e-2;
const double pi=acos(-1);
ll a[200005],dp[200005];
bool cmp(ll a,ll b){
    return a>b;
}
int main(){
    int t;
    scanf("%d",&t);
    while (t--){
        int n;
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+1+n,cmp);
        if (n<=6)
        {
            printf("%lld\n",2LL*(a[1]-a[n]));
            continue;
        }
        dp[4]=a[1]-a[4];dp[6]=a[1]-a[6];dp[8]=a[1]+a[5]-a[4]-a[8];
        for (int i=10;i<=n;i+=2){
            dp[i]=min(dp[i-4]+a[i-3]-a[i],dp[i-6]+a[i-5]-a[i]);
        }
        printf("%lld\n",2*dp[n]);
    }
    return 0;
}
```c

你可能感兴趣的:(牛客题解)