UVALive - 6434 Number Assignment

分析:由题,我们需要决定新的容器放置的位置。

可以采用dp的方法

dp[j][i]代表到第j个数第i个容器的最优情况

对于dp[j][i]尝试在可能每个地方放置的新容器找最小值

状态转移方程 dp[j][i]=min(dp[j][i],dp[j-k][i-1]+a[j]-a[j-k+1]);

代码如下

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <cstring>
using namespace std;
#define INF 0x7fffffff
typedef long long ll;
ll c[110];
ll a[110];
ll dp[110][110];
int main()
{
    std::ios::sync_with_stdio(false);
    int t,n,m,cnt,h,z;
    ll sum;
   cin>>t;
    for(int k=1;k<=t;k++)
    {
        memset(a,0,sizeof(a));
        memset(dp,0,sizeof(dp));
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
        cin>>a[i];
     }
     sort(a+1,a+n+1); 
     for(int i=1;i<=n;i++)
     {
          dp[i][1]=a[i]-a[1];
     }
    for(int i=2;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            dp[j][i]=INF;
            for(int k=1;j-k>=i-1;k++)//j-k代表上一个容器为止所装的所有数,必然大于容器数量i-1
            {
                dp[j][i]=min(dp[j][i],dp[j-k][i-1]+a[j]-a[j-k+1]);
            }
        }
    }
      printf("Case #%d: %lld\n",k,dp[n][m]);
  } 
       return 0;
}

自己需要注意的问题: 在dp的时候常常用的数组下标是从1开始进行赋值的,所以在排序的时候是sort(a+1,a+n+1);

                       

posted @ 2017-04-13 16:45  hinata_hajime  阅读(133)  评论(0编辑  收藏  举报