hdoj 1421 搬寝室

http://acm.hdu.edu.cn/showproblem.php?pid=1421

刚开始想的时候,想转化成背包来做,但是不好表示,

然后考虑到dp中的有几个相关元素,这里有两,一个是物品个数,一个是选择的对数,那么有了状态

 dp[i][j]表示前i件物品选择j对所付出的代价,那么对于第i件有选与不选两种,所以

 dp[i][j]=min((dp[i-2][j-1]+charge(weight[i-1],weight[i])),dp[i-1][j]);

即这件物品要选的话那么前一件和他是一对的,则代价是他们两的代价加上dp[i-2][j-2],如果这件物品不选则dp[i-1][j],前i-1件选j对

初始化的时候要注意,dp【i】【0】=0;

View Code
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#define maxn 2200
#define inf  100000
using namespace std;
int  weight[maxn];
int  dp[maxn][1100];
int  charge(int a,int b)
{
    return (a-b)*(a-b);
}
int min(int a,int b)
{
    return a<b?a:b;
}
int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        memset(dp,127,sizeof(dp));
       /* for(int i=0;i<=10;i++)
        {
            for(int j=0;j<=10;j++)
            cout<<dp[i][j]<<" ";
            cout<<endl;
        }*/

        memset(weight,0,sizeof(weight));
        for(int i=1;i<=n;i++)
        scanf("%d",&weight[i]);
        sort(weight+1,weight+1+n);//要排序,因为相邻的差的最小
        for(int i=0;i<=n;i++)
        dp[i][0]=0;//初始化
        for(int i=2;i<=n;i++)
        {
            for(int j=1;j*2<=i;j++)
            {
                dp[i][j]=min((dp[i-2][j-1]+charge(weight[i-1],weight[i])),dp[i-1][j]);
            }
        }
        printf("%d\n",dp[n][k]);

    }
    return 0;
}
原文地址:https://www.cnblogs.com/cs1003/p/2661920.html