hiho刷题日记——第六天01背包
来源:互联网 发布:淘宝试衣间在哪 编辑:程序博客网 时间:2024/05/21 09:06
简单的01背包问题,简单的说就是将已有的资源发挥出最大的价值。
每组测试数据的第一行为两个正整数N和M,表示奖品的个数,以及奖券数。
接下来的N行描述每一行描述一个奖品,其中第i行为两个整数need(i)和value(i),意义如前文所述。
测试数据保证
对于100%的数据,N的值不超过500,M的值不超过10^5
对于100%的数据,need(i)不超过2*10^5, value(i)不超过10^3
直接动态规划
定义int f(int n,int m)为 从第n个物品开始考虑,在还有m个资源的情况下能发挥的最大价值。
则有:
int f(int n,int m)
{
if(n==N) return 0;
int t1=f(n+1,m);
int t2=0;
if(m>=need[n]) t2=f(n+1,m-need[n])+value[n]; //唯一需要注意的就是当前资源足够时,才能发挥对应的价值。有m>=need[n]
return t1>t2?t1:t2;
}
以上代码确实可以解决这个01背包问题。
但是以上代码的运算速度太慢。
而且不能用一般的记忆化,因为所需空间(500*100000*4b)太大。
若将选择考虑顺序倒过来,考虑到在计算的过程中有一下情况:
为求f(n,m) 就得求得 f(n-1,m)和f(n-1,m-need[n])+value[n]。
若当前记录下f(n,m),在求f(n+1,m)的时候,f(n-1,m)和f(n-1,m-need[n])的值就用不着了。
所以用来做记忆化的数组就可以把n这个参数去掉,只需要一维就够了。int ans[M+1];
for(int n=0;n<N;n++)
for(int i=M;i>=need[n];i--)
{
int t1=ans[i];
int t2=ans[i-need[n]]+value[n];
ans[i]=t1>t2?t1:t2;
}
全代码:
#include<cstdio>
#include<cstring>
using namespace std;
int N,M;
int need[501],value[501];
int ans[100001];
int f()
{
for(int n=0;n<N;n++)
for(int i=M;i>=need[n];i--)
{
int t1=ans[i];
int t2=ans[i-need[n]]+value[n];
ans[i]=t1>t2?t1:t2;
}
return ans[M];
}
int main()
{
memset(ans,0,sizeof(ans));
scanf("%d%d",&N,&M);
for(int i=0;i<N;i++)
scanf("%d%d",&need[i],&value[i]);
printf("%d",f());
return 0;
}
- hiho刷题日记——第六天01背包
- hiho刷题日记——第七天完全背包
- hiho第六周——01背包(动态规划)
- hiho第六周 01背包
- hiho第六周--01背包
- hiho刷题日记——第十二天刷油漆
- hiho刷题日记——第二天Trie树
- hiho刷题日记——第四天Trie图
- hiho刷题日记——第一天 A+B
- hiho刷题日记——第三天KMP算法
- hiho刷题日记——第五天数字三角形
- hiho刷题日记——第十天后序遍历
- hiho刷题日记——第十六天RMQ-ST算法
- hiho刷题日记——第二十二天更为复杂的买卖房屋姿势
- hiho刷题日记——第二十六天最小生成树一·Prim算法
- hiho一下 第六周 Hihocoder #1038 : 01背包
- 东软睿道实训日记—第六天
- hiho刷题日记——第三十天小Hi小Ho的惊天大作战:扫雷·一
- fmdb简介与使用
- SQL server理论知识
- hdu 5525(数学题)
- 让DIV垂直居中+水平居中+圆角属性
- 日常生活英语口语怎么学
- hiho刷题日记——第六天01背包
- 适配器模式
- Codeforces Round #192 (Div. 1) C. Graph Reconstruction (随机化算法)
- Android源码分析-Alarm机制与Binder的交互
- 使用DrawImage函数进行拉伸绘制时出现的过度边沿现象
- 喜马拉雅听 手机端协议分析
- hdu 4672 Present Day, Present Time(博弈)
- 【MySQL】mysql中模糊查询的四种用法
- 使用oschina的git服务器图文流程