• codeforces 571B


    题意:

    给定n,k和数组A,重排数组A,最小化  。

    题解:

    考虑这个东西是隔k个取一个,所以我们把下标按照mod k分类,分成k组

    显然每组内部尽量最小化max-min,所以我们考虑给A排序,然后选连续的一段。

    显然这k组中有A个size为M,B个size为M+1

    所以我们dp[i][x,y]表示选到第i个,x个size为M的,y个size为M+1的

    因为k<=5000,所以有效状态数很少

     1 #include<bits/stdc++.h>
     2 #define pii pair<int,int>
     3 #define mp(a,b) make_pair(a,b)
     4 #define maxn 300005 
     5 #define ll long long
     6 using namespace std;
     7 int n,k;
     8 ll a[maxn];
     9 map<pii,ll> dp[maxn];
    10 int main()
    11 {
    12     scanf("%d%d",&n,&k);
    13     for(int i=1;i<=n;++i)scanf("%I64d",&a[i]);
    14     sort(a+1,a+n+1);
    15     int A=0,B=0,M=0;
    16     for(int s=1;s<=k;++s)
    17     {
    18         int cnt=0;
    19         for(int i=s;i<=n;i+=k)++cnt;
    20         M=max(M,cnt);
    21     }
    22     --M;
    23     for(int s=1;s<=k;++s)
    24     {
    25         int cnt=0;
    26         for(int i=s;i<=n;i+=k)++cnt;
    27         if(cnt==M)++A;
    28         if(cnt==M+1)++B;
    29     }
    30     dp[0][mp(0,0)]=0;
    31     map<pii,ll>::iterator it;
    32     for(int i=0;i<n;++i)
    33     {
    34         for(it=dp[i].begin();it!=dp[i].end();++it)
    35         {
    36             int x=(it->first).first,y=(it->first).second;
    37             if(x<A)
    38             {
    39                 if(!dp[i+M].count(mp(x+1,y)))dp[i+M][mp(x+1,y)]=(it->second)+a[i+M]-a[i+1];
    40                 else dp[i+M][mp(x+1,y)]=min(dp[i+M][mp(x+1,y)],(it->second)+a[i+M]-a[i+1]);
    41             }
    42             if(y<B)
    43             {
    44                 if(!dp[i+M+1].count(mp(x,y+1)))dp[i+M+1][mp(x,y+1)]=(it->second)+a[i+M+1]-a[i+1];
    45                 else dp[i+M+1][mp(x,y+1)]=min(dp[i+M+1][mp(x,y+1)],(it->second)+a[i+M+1]-a[i+1]);
    46             }
    47         }
    48     }
    49     printf("%I64d
    ",dp[n][mp(A,B)]);
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    对拍源码QwQ
    BZOJ-3875: [Ahoi2014&Jsoi2014]骑士游戏(SPFA+DP)
    2017年10月19日23:31:57
    BZOJ-1064: [Noi2008]假面舞会 (综合性图论题)
    BZOJ-1002: [FJOI2007]轮状病毒(打表找规律or递推 + 高精度)
    BZOJ1397 Ural 1486 Equal squares
    BZOJ3417 Poi2013 Tales of seafaring
    BZOJ2286 [Sdoi2011消耗战
    BZOJ1370 [Baltic2003]Gang团伙
    BZOJ2530 [Poi2011]Party
  • 原文地址:https://www.cnblogs.com/uuzlove/p/10464963.html
Copyright © 2020-2023  润新知