hdoj1421 搬寝室(基础DP)

来源:互联网 发布:2016淘宝客教程视频 编辑:程序博客网 时间:2024/05/29 09:22

题目:点击打开链接

一个简单的DP题目,我们可以这样思考,为了使疲劳度最低,我们则需要左右手拿的物品接近,则是a1<a2<a3<a4<a5<a6,这样的序列数,我们则是采取拿a1,a2和拿a3,a4,这样的结果则是疲劳度最低。

DP[i][j]表示拿i件物品需要搬j对.

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

分析:第i件物品不搬,则是在前i-1件物品中搬j对

    第i件物品搬,则i-1件物品也要搬,那么则是在前i-2件物品中搬j-1对,再搬第i件

需要注意的是:

1.当2*j<i时,即要搬得数量超过了物品总量,这是不可能发生的,因此此时令dp[i][j]为无穷大.

2.当j==0时,即在一对物品都没搬时,疲劳值为0,此时dp[i][j]=0.

#include <stdio.h>#include <string.h>#include <math.h>#include <iostream>#include <stdlib.h>#include <algorithm>#include <map>#include <queue>using namespace std;const int INF=0x7ffffff;int dp[2001][2001];int a[2010];int DP(int i,int j){if(j*2>i)return INF;if(j==0)return 0;return dp[i][j];}int main(){int n,k,i,j;while(cin>>n>>k){for(i=1;i<=n;i++)cin>>a[i];sort(a+1,a+n+1);for(i=1;i<n;i++){a[i]=a[i+1]-a[i];a[i]*=a[i];}for(j=1;j<=k;j++){for(i=2;i<=n;i++){dp[i][j]=min(DP(i-1,j),DP(i-2,j-1)+a[i-1]);}}cout<<dp[n][k]<<endl;}return 0;}


0 0
原创粉丝点击