北京師範大學第十四屆ACM決賽- F Training Plan
阿新 • • 發佈:2019-02-09
題意:小Q同學為了準備今年的ICPC Regional,計劃在m天之內刷掉n道題,每道題有一個難度值,其中第i道題的難度值為a[i]。
然而處於半頹廢狀態中的小Q同學不希望在同一天中做難度差距懸殊的題目,定義第i天中刷的題的難度的最大值減最小值為d[i](如果第i天沒有刷題,則d[i]=0),那麼整個計劃的難度為。
然而處於半頹廢狀態中的小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(); } }