我想哼唱史诗般的歌曲,你愿坐下来聆听么!!!
这是一题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;
}