1. 程式人生 > >北京師範大學第十四屆ACM決賽- F Training Plan

北京師範大學第十四屆ACM決賽- F Training Plan

題意:小Q同學為了準備今年的ICPC Regional,計劃在m天之內刷掉n道題,每道題有一個難度值,其中第i道題的難度值為a[i]。
然而處於半頹廢狀態中的小Q同學不希望在同一天中做難度差距懸殊的題目,定義第i天中刷的題的難度的最大值減最小值為d[i](如果第i天沒有刷題,則d[i]=0),那麼整個計劃的難度為

小Q同學可以按照任意的順序刷題,並且一天中可以刷任意多道題,但是每道題只需要做一次,現在小Q同學想知道完成這個計劃的總難度的最小值是多少。

思路:暴力三重for迴圈dp所有可能結果。

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#define siz 505
#define LL long long
using namespace std;
int n,m;
int gp[siz];
LL dp[siz][siz];
void solve()
{
    LL x;
    for(int i=1; i<=n; i++)
    {
        x = gp[i] - gp[1];
        dp[1][i] = x * x;
    }
    for(int i=2; i<=m; i++)
    {
        for(int j=1; j<=n; j++)
        {
            dp[i][j] = 1ll*(gp[j] - gp[1]) * (gp[j] - gp[1]);
            for(int k=2; k<=j; k++)
            {
                x = gp[j] - gp[k];
                dp[i][j] = min(dp[i-1][k-1] + x * x,dp[i][j]);
            }
        }
    }
    printf("%lld\n",dp[m][n]);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
 
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&gp[i]);
        }
        if(n<=m)
        {
            printf("%d\n",0);
            continue;
        }
        sort(gp+1,gp+n+1);
        solve();
    }
}