hdu 1421 动态规划

本文介绍了如何解决杭电1421题动态规划问题,通过状态压缩dp来找到从n个数中选取k对,使得疲劳度最小的策略。首先对数列进行排序,然后定义状态dp[i][j]表示从前i个数中选取j对的最优解,并给出状态转移方程。最后提供了一个AC代码示例。
摘要由CSDN通过智能技术生成

这两天一直在做动态规划题:昨天做了杭电的1074 状态压缩dp题,因为是以前从来没接触过状态dp,所以费了很久

时间直到今天才弄明白~下午又看了一道相对简单点的动归题~现在尽量讲明白思路:




1421 题得先弄明白题意,从n个数中选出k对来,使得最终的疲劳度最小。

第一步 从小到大对n个数排序。。。。

第二步 先确定状态:dp[  i ][  j  ]表示从前i个数中选取j对的最优解。。

第三步 确定状态转移方程 (如果 第 i 个数被选了,那么它肯定是和第i-1个数作一对)

所以: dp[  i  ][   j  ]=min(dp[ i-2 ][ j-1 ]+(a[ i ]-a[ i-1 ])*(a[ i ]-a[ i-1 ]),dp[ i-1 ][  j  ]);

最后实现代码,注意代码实现的过程中一个点 就是dp初始化的问题;

附上ac代码

#include <iostream>
using namespace std;
int a[2100],dp[2100][1005];
int cmp(const void *a,const void *b)
{
  return *(int *)a-*(int *)b;  
}
int main()
{
  int n,k;
  while(cin>>n>>k)
  {
    for(int i=1;i<=n;i++)
        cin>>a[i];
     qsort(a+1,n,sizeof(int),cmp);   
    for(int i=0;i<=n;i++)
    {
      for(int j=0;j*2<=n+2;j++)
          if(j*2>i)dp[i][j]=100000000;
    }
    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]+(a[i]-a[i-1])*(a[i]-a[i-1]),dp[i-1][j]);
    }
    cout<<dp[n][k]<<endl;
  }
  return 0;  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值