您的位置:首页 > 其它

HDU 1421 搬寝室 类似背包DP

2013-08-29 10:33 288 查看
 

思路:把重物从小到大排序,计算出每2个相邻的重物产生的疲劳度,放在p[i]数组中,表示i与i+1这2个重物产生的疲劳度。 

dp[i][j]表示进行到第i个物品(i前面的物品不一定都选了,跟背包差不多,i表示进行到第i个物品),已经选了j对物品 产生的最小疲劳度。

初始化:

先把所有值赋值为INF(无穷大),然后dp[i][0]=0;(0<=i<=n)因为没选重物之前疲劳度为0;

for(i=0;i<=n;i++)
for(j=0;j<=k;j++)
dp[i][j]=INF;
for(i=0;i<=n;i++)dp[i][0]=0;


 

则状态转移方程为:

dp[i-1][j]表示没有选i这个物品, 当选了i这物品后就必须选i-1这个物品,选了这两个物品,那状态变为dp[i-2][j-1]+p[i-1];

dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+p[i-1])


AC代码




View Code

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define INF 100000000
int a[2001],p[2001];
int dp[2001][1001];
int main()
{
int i, j,n, k;
while(~scanf("%d%d",&n,&k))
{
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(i=1;i<n;i++)
p[i]=(a[i+1]-a[i])*(a[i+1]-a[i]);
for(i=0;i<=n;i++)
for(j=0;j<=k;j++)
dp[i][j]=INF;
for(i=0;i<=n;i++)dp[i][0]=0;
for(i=2;i<=n;i++)
{
for(j=1;j<=k;j++)
dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+p[i-1]);
}
printf("%d\n",dp
[k]);
}
return 0;
}


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: