【动态规划】背包问题
来源:互联网 发布:淘宝改版中国质造 编辑:程序博客网 时间:2024/06/11 17:36
瞎了眼了,这套题全是卖萌卖够了给你一拳。
题目描述追求简洁无极限。
背包问题
【题目描述】
有一个容量为W的背包,有N种物品,第i种物品的体积为Ti,价值为Vi。
对于每种物品,你可以选择是否将它放入背包,放入背包的物品的总体积不能超过W,在这个前提下你希望放入背包的物品的总价值最大。
【输入数据】
第一行两个数W,N,表示背包的容量和物品的数量。
之后N行,每行两个数Ti,Vi,表示第i件物品的体积和价值。
【输出数据】
输出一个数,放入背包的物品的最大总价值。
【样例】
bag.in
bag.out
9 3
7 14
5 9
4 7
16
【数据规模】
测试点编号
N
W
1
10
100
2
10
100
3
1000
10000
4
1000
10000
5
50
10000000
6
70
10000000
7
100
10000000
8
120
10000000
9
150
100000000
10
200
100000000
尼玛谁看到这么简单的题还去想复杂方法?结果超时6组。。
题目范围太坑爹,加之没有说清楚。。其实题上漏掉了一个条件,就是总价值不超过100000,可以添到题设中去。
所以我们可以分两种情况,普通01背包最大限度是N*W=1000*10000。超出这个范围我们就换一种思路。
f[i][j] 表示 前i种物品 价值为j ,最少体积是多少次。同样可以就地滚动。
加注释的是改进了的地方,一开始还是超时,修改了一个地方,对如果算出来的新体积比W大了,就不更新(其实这只是优化了一点小小的系数,因为如果不加这个优化,状态转移是两个时钟周期,加上了可以优化到接近一个。= =、这是多么小一个优化呀。实际执行效果很好。)
#include <cstdio>#include <string>#include <cstring>#define MAX(a,b) ((a)>(b)?(a):(b))#define MIN(a,b) ((a)<(b)?(a):(b))long getint(){long rs=0;bool sgn=1;char tmp;do tmp = getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp == '-'){tmp=getchar();sgn=0;}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;}//long w[1010];//long v[1010];long f[1000010];int main(){freopen("bag.in","r",stdin);freopen("bag.out","w",stdout);long W = getint();long n = getint();//for (long i=1;i<n+1;i++)//{//w[i] = getint();//v[i] = getint();//}if (W <= 10000){for (long i=1;i<n+1;i++){long w = getint();long v = getint();for (long j=W;j>=w;j--){f[j] = MAX(f[j],f[j-w]+v);}}long ans = 0;for (long i=0;i<W+1;i++)ans = MAX(ans,f[i]);printf("%ld",ans);}else{memset(f,0x7f,sizeof f);f[0] = 0;for (long i=1;i<n+1;i++){long w = getint();long v = getint();for (long j=1000000;j>=v;j--){//if (f[j-v]+w <= W)//f[j] = MIN(f[j],f[j-v]+w);}}for (long j=1000000;j>=0;j--)if (f[j] <= W){printf("%ld",j);break;}}return 0;}
另附一个开散列优化的版本1(事实证明,用这种方法使空间压力更大了,几乎是难以承受)主要弊端在于
it1 = hash[now].find(it2->first);if (it1 == hash[now].end())hash[now].insert(*it2);elseit1 -> second = MAX(it1->second,it2->second);因为实际上我是用的01滚动的原理,来搞的,但是其实只有f数组需要01滚动(为了解决后效性问题),而hash表(我也不知道为什么我要)是不需要滚动的(因为01背包,每一种体积都会保留到下一个阶段)
#include <string>#include <cstring>#include <cstdio>#define MAX(a,b) ((a)>(b)?(a):(b))#include <map>using std::map;using std::iterator;using std::make_pair;long w[1010];long v[1010];long f[10000010];long getint(){long rs=0;bool sgn=1;char tmp;do tmp = getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp == '-'){tmp=getchar();sgn=0;}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;}map<long,long> hash[2];map<long,long>::iterator it1;int main(){freopen("bag.in","r",stdin);freopen("bag.out","w",stdout);long W = getint();long n = getint();for (long i=1;i<n+1;i++){w[i] = getint();v[i] = getint();}long pre = 0;long now = 1;hash[now][0] = 0;for (long i=1;i<n+1;i++){pre ^= 1;now ^= 1;hash[now].clear();for (map<long,long>::iterator it2=hash[pre].begin();it2!=hash[pre].end();it2++){if (it2->first+w[i] <= W){it1 = hash[now].find(it2->first+w[i]);if (it1 == hash[now].end())hash[now].insert(make_pair(it2->first+w[i],it2->second+v[i]));elseit1 -> second = MAX(it1->second,it2->second+v[i]);}it1 = hash[now].find(it2->first);if (it1 == hash[now].end())hash[now].insert(*it2);elseit1 -> second = MAX(it1->second,it2->second);}}long ans = 0;for (map<long,long>::iterator it2=hash[now].begin();it2!=hash[now].end();it2++){ans = MAX(ans,it2->second);}printf("%ld",ans);return 0;}
基于以上问题,做了优化,实际效果也不理想
#include <string>#include <cstring>#include <cstdio>#define MAX(a,b) ((a)>(b)?(a):(b))long w[1010];long v[1010];long weight[2][5000000];long f[2][5000000];long ths = 0;long pre = 1;const long hmod = 200000;long getint(){long rs=0;bool sgn=1;char tmp;do tmp = getchar();while (!isdigit(tmp)&&tmp-'-');if (tmp == '-'){tmp=getchar();sgn=0;}do rs=(rs<<3)+(rs<<1)+tmp-'0';while (isdigit(tmp=getchar()));return sgn?rs:-rs;}long cnt[2];struct node{long s;long id;node* nxt;};node* head[hmod+10];node memory[5000000];long get_id(long s){long h = s % hmod;for (node* u=head[h];u;u=u->nxt)if (u->s == s) return u->id;cnt[ths] ++;f[ths][cnt[ths]] = 0;node* nn = &memory[cnt[ths]];nn -> nxt = head[h];nn -> id = cnt[ths];nn -> s = s;head[h] = nn;weight[ths][cnt[ths]] = s;return cnt[ths];}void clear(){cnt[ths] = 0;memset(head,0,sizeof head);}void updata(long &a,long b){if (b > a)a = b;}int main(){freopen("bag.in","r",stdin);freopen("bag.out","w",stdout);long W = getint();long n = getint();for (long i=1;i<n+1;i++){w[i] = getint();v[i] = getint();}f[ths][get_id(0)] = 0;for (long i=1;i<n+1;i++){pre ^= 1;ths ^= 1;clear();for (long j=1;j<cnt[pre]+1;j++){if (weight[pre][j]+w[i] <= W)updata(f[ths][get_id(weight[pre][j]+w[i])],f[pre][j]+v[i]);updata(f[ths][get_id(weight[pre][j])],f[pre][j]);}}long ans = 0;for (long j=1;j<cnt[ths]+1;j++){ans = MAX(ans,f[ths][j]);}printf("%ld",ans);return 0;}
- 动态规划 背包问题
- 【动态规划】背包问题
- 动态规划-背包问题
- 动态规划+背包问题
- 动态规划-背包问题
- 背包问题 -- 动态规划
- 《背包问题》 动态规划
- 动态规划-背包问题
- 动态规划 背包问题
- 动态规划 背包问题
- 动态规划 背包问题
- 动态规划 背包问题
- 动态规划-背包问题
- 动态规划--背包问题
- 动态规划背包问题
- 背包问题 动态规划
- 动态规划-背包问题
- 动态规划-背包问题
- java 远程调试butterfly
- Warning: The Copy Bundle Resources build phase contains this target's Info.plist file 'Info
- 多线程 NSThread
- java实现标点全角/半角转换
- 关于sfo的备注和bo的备注字段
- 【动态规划】背包问题
- 读书笔记整理八:智能基础结构增强功能11g
- 程式中打开windows上本机已存在的服务
- 百度手机地图升级“彩色蚯蚓”
- 线段相交:Intersection
- 计时器(2)之数字时钟
- IT男标准装备
- ADC10多路转换
- IT女上班标准装备图