hdu2546

我想哼唱史诗般的歌曲,你愿坐下来聆听么!!!

这是一题01背包问题。做之前最好先了解一下。

01背包问题大意就是有一个容量为V 的包,然后要往里面装东西。装的物品的体积是v[i],它的价值是w[i].

那么我们可以得到下面一条递推方程。

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

//f[i][v] 表示前 i 件物品恰放入一个容量为 v 的背包可以获得的最大价值。

意思:

将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。

这里我们可以得到通用的模板:

for(i = 1; i<=n; i++)
{
for(j = v; j>=c[i]; j--)//在这里,背包放入物品后,容量不断的减少,直到再也放不进了
{
f[i][v]=max(f[i-1][v],f[i-1][v-c[i]]+w[i]);
}
}

这个是背包九讲,百度文库上的,讲得挺好

http://wenku.baidu.com/view/8b3c0d778e9951e79b892755.html

题目:
http://acm.hdu.edu.cn/showproblem.php?pid=2546

#include <iostream>
#include <algorithm> 
#include <stdio.h>
#include <cmath>
using namespace std;

int cmp(int a,int b)
{
 return a<b;
}

int max(int a,int b)
{
 if(a<b)return b;
 else return a;
}
int main()
{
 
 int n,m,i,j,MAX;
 while(scanf("%d",&n) && n!=0)
 {
  int price[1002]={0},dp[1002]={0};
  for(i=1;i<=n;i++)
  {
   cin>>price[i];
  }
  sort(price+1,price+1+n,cmp);
  MAX=price[n];
  cin>>m;
  if(m<5)
  {
   cout<<m<<endl;
   continue;
  }
  m=m-5; //这里用多余5块的钱买最多的东西才最实惠
  for(i=1;i<n;i++)
  {
   for(j=m;j>=price[i];j--)//在这里,背包放入物品后,容量不断的减少,直到再也放不进了
   {
    dp[j]=max(dp[j],(dp[j-price[i]]+price[i]));
   }
  }
  cout<<m+5-dp[m]-MAX<<endl;
 }
 return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值