• Codeforces 571B Minimization:dp + 贪心【前后相消】


    题目链接:http://codeforces.com/problemset/problem/571/B

    题意:

      给你一个长度为n的数列a[i]。

      现在你可以随意改变数字的位置,问你 ∑| a[i] - a[i+k] | 的最小值(1 <= i <= n-k)。

    题解:

      将a[i]拆成若干个子序列s[j],子序列中相邻两数在a[i]中的距离为k。

      此时原式 = ∑(子序列s[j]内部之差的和)

     

      显然,要想使子序列s[j]内部之差的和尽可能小,子序列s[j]内部一定为升序。

      显然,要想使 ∑(子序列s[j]内部之差的和)尽可能小,所有子序列s[j]一定是由a[i]升序排序后分割而来。

      可以发现,拆出的子序列中:

        有 n2 = n%k 个子序列长度为 l1 = n/k+1

        有 n1 = k-n%k 个子序列长度为 l2 = n/k

      此时:

        原式 = ∑ (s[2]-s[1]+s[3]-s[2]+s[4]-s[3]...)

      前后相消之后就是:

        原式 = ∑ (s[i][end] - s[i][1])

      此时题目就变成了:

        先将a[i]排序,然后将a[i]分割成n1个长为l1的子串,以及n2个长为l2的子串。

        让你使得 ∑ (s[i][end] - s[i][1])最小。

      表示状态:

        dp[i][j]

        表示从头开始分割,已经分割出了i个长为l1的子串,以及j个长为l2的子串。

      找出答案:

        ans = dp[n1][n2]

      如何转移:

        if(i) dp[i][j] = min(dp[i][j], dp[i-1][j]+a[start1]-a[end1])

        if(j) dp[i][j] = min(dp[i][j], dp[i][j-1]+a[start2]-a[end2])

        start1/2, end1/2分别是新分割出的子串的首位与末尾。

      边界条件:

        dp[0][0] = 0

        others = INF

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define MAX_N 300005
     6 #define MAX_S 5005
     7 
     8 using namespace std;
     9 
    10 int n,k;
    11 int a[MAX_N];
    12 long long dp[MAX_S][MAX_S];
    13 
    14 int main()
    15 {
    16     cin>>n>>k;
    17     for(int i=1;i<=n;i++) cin>>a[i];
    18     sort(a+1,a+n+1);
    19     int n1=n%k,n2=k-n%k;
    20     int l1=n/k+1,l2=n/k;
    21     memset(dp,0x3f,sizeof(dp));
    22     dp[0][0]=0;
    23     for(int i=0;i<=n1;i++)
    24     {
    25         for(int j=0;j<=n2;j++)
    26         {
    27             if(i) dp[i][j]=min(dp[i][j],dp[i-1][j]+a[i*l1+j*l2]-a[(i-1)*l1+j*l2+1]);
    28             if(j) dp[i][j]=min(dp[i][j],dp[i][j-1]+a[i*l1+j*l2]-a[i*l1+(j-1)*l2+1]);
    29         }
    30     }
    31     cout<<dp[n1][n2]<<endl;
    32 }
  • 相关阅读:
    [Leetcode]设计链表
    [Leetcode]最小栈
    复杂JSON反序列化为类对象
    Big Data Solution in Azure: Azure Data Lake
    EF vs ADO.NET
    EF5.0默认不支持DB First了?
    WebService/WCF/WebAPI区别
    AugularJS1.X不升级到2.X
    数据库中锁的问题
    MVC中路由匹配的规则
  • 原文地址:https://www.cnblogs.com/Leohh/p/8214560.html
Copyright © 2020-2023  润新知