01背包 hdu2546 hdu2602
来源:互联网 发布:mac pro垃圾桶 玩游戏 编辑:程序博客网 时间:2024/05/22 01:28
01背包的思想呢,也是dp的思想吧,把问题转化为子问题求解,不断继承状态得到最后的答案。
贴个公式:f[i][v]=max(f[i-1][v],f[i-1][v-c[i]]+w[i]);f[i][v]表示的是前i件物品放在一个容量为v的背包里可以获得的最大值。我也不明白这个二维数组的实用性在哪里,我都是写一维的数组,也弱的只会一维的勒,然后一维的话,两个for循环,第一个循环的是物品的第几个第几个,第二个循环是背包的重量,此处重点是,第二个循环是逆序的循环,是从背包的最大值开始的,因为呢,继承的值是一次的,学长当时讲的是自下而上,自左向右填表的,当时我模拟填表的时候换行填时,是先从v=v开始找[v-w[i]]的,而不是从v=0开始找的,然后在比较权值能不能改变,之后再进行继承那个较大的值,所以我觉得这里逆序的可以这样理解,算是强行理解下吧。
一维是优化过(空间)的:dp[v]=max(dp[v],dp[v-a[i]]+val[i]);a[i]是物品的在背包里需要占有的背包容量,可以是重量啊,体积啊什么的。val[i]是物品的权值。
然后贴题目和代码:hdu 2546
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。
n=0表示数据结束。
1505101 2 3 2 1 1 2 3 2 1500
-4532
把剩下的那个五块钱单独拿出来买价值最大的物品就行啦:
#include<bits/stdc++.h>
using namespace std;
int cmp(int a,int b)
{
return a<b;
}
int main()
{
int dp[1005],a[1005];
int n,m,i,j;
while(scanf("%d",&n)&&n)
{
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
for(i=0;i<n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
sort(a,a+n,cmp);
if(m<5)
{
cout<<m<<endl;
continue;
}
m-=5;
for(i=0;i<n-1;i++)
for(j=m;j>=a[i];j--)
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
//cout<<dp[45]<<" "<<a[n-1]<<endl;
cout<<m-dp[m]+5-a[n-1]<<endl;
}
return 0;
}
还有个模板题 hdu 2602:
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
15 101 2 3 4 55 4 3 2 1
14
记性太差,模板过也贴一下把:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int dp[1005],a[1005],b[1055];
int n,m,i,j,v,t;
scanf("%d",&t);
while(t--)
{
//memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&v);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
scanf("%d",&b[i]);
for(i=0;i<n;i++)
for(j=v;j>=b[i];j--)
dp[j]=max(dp[j],dp[j-b[i]]+a[i]);
cout<<dp[v]<<endl;
}
return 0;
}
- 01背包 hdu2546 hdu2602
- 简单的背包问题(入门)HDU2602 HDU2546 HDU1864
- HDU2546 01背包
- HDU2546:饭卡(01背包)
- hdu2546 饭卡 (01背包)
- hdu2546饭卡-01背包
- hdu2546饭卡 (01背包)
- HDU2546:饭卡(01背包)
- HDU2546 饭卡 01背包
- hdu2546 01背包
- HDU2546 (01背包)
- HDU2546 饭卡(01背包)
- HDU2546 01背包
- 【HDU2546】饭卡(01背包)
- 【01背包】HDU2546饭卡
- HDU2546(01背包)
- hdu2546饭卡(01背包)
- hdu2546-01背包
- Map
- 题解:换低档装置(UVa 1588)
- 在MATLAB中使用LaTex字符的方法
- hadoop2.7.3下spark2.1.0安装_yarn作业提交
- 图论之拓扑排序
- 01背包 hdu2546 hdu2602
- Windows+VS2015编译caffe+py-faster-rcnn
- BZOJ1079[SCOI2008]着色方案
- C++第5次实验作业
- L1-032. Left-pad
- Android emulator 常用功能举例
- PYTHON魔法方法小笔记
- QTextStream 读取文件内容
- 经典神经网络回顾