博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nyoj 1091 还是01背包(超大数dp)
阅读量:4355 次
发布时间:2019-06-07

本文共 1263 字,大约阅读时间需要 4 分钟。

描述

有n个重量和价值分别为 wi 和 vi 的物品,从这些物品中挑选总重量不超过W的物品,求所有挑选方案中价值总和的最大值

1 <= n <=40

1 <= wi <= 10^15

1 <= vi <= 10^15

1 <= W <= 10^15

分析:在做的时候毫无头绪,在网上看了其他大神的博客才AC了,数据超大无法使用之前的思路(超时且dp数组开不了这么大),但是由本题条件可知n的值非常小,可用递归配合剪枝解题

代码:

#include
#include
#include
#define Max(a, b) a > b ? a:busing namespace std;typedef long long ll;const ll INF = 1000000000000000;ll w[45], v[45];ll sw[45], sv[45];ll n, W, ans;void solve(int i, ll W, ll V) { if(i == 0) { ans = Max(ans, V); return; } if(W == 0 || ans >= V + sv[i]) return;//背包满或者当前总的加上这个前i个的总价值小于当前的总value,这步是剪枝 if(W >= sw[i]) {
//因为是从上往下找的,所以只要当前容量能装下前i个的和,所以这时一定是最大的 ,剪枝 V += sv[i]; ans = Max(ans, V); W = 0; return; } if(w[i] <= W) solve(i-1, W - w[i], V + v[i]); solve(i-1, W, V);}int main() { while(cin >> n >> W) { ans = -1; memset(sw, 0, sizeof(sw)); memset(sv, 0, sizeof(sv)); for(int i = 1; i <= n; i++) { cin >> w[i] >> v[i]; sw[i] = sw[i-1] + w[i]; sv[i] = sv[i-1] + v[i]; } solve(n, W, 0); cout << ans << endl; } return 0;}

 

转载于:https://www.cnblogs.com/kindleheart/p/8870742.html

你可能感兴趣的文章
小D课堂 - 零基础入门SpringBoot2.X到实战_第11节 Logback日志框架介绍和SpringBoot整合实战_45、SpringBoot2.x日志讲解和Logback配置实战...
查看>>
类中的静态函数和非静态函数的区别
查看>>
windows 下安装Apache
查看>>
Fedora14 mount出现错误时解决办法【亲测有效】
查看>>
使用Visual Studio 2013进行UI自动化测试
查看>>
13-集体照
查看>>
读了曾国藩家书,,心态逐渐平和起来。搞技术的如果缺乏信念的指引,生活会很乏味无聊!...
查看>>
160809308周子济第六次作业
查看>>
sublime text3最新版本注册码(build 3143)
查看>>
linux使用技巧
查看>>
必背公式及常数
查看>>
利用CSS、JavaScript及Ajax实现图片预加载的三大方法
查看>>
js时间戳转时间格式
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Linux的用户态和内核态
查看>>
JavaScript原生错误及检测
查看>>
(原创) cocos2d-x 3.0+ lua 学习和工作(4) : 公共函数(3): 深度克隆clone()
查看>>
为什么写作
查看>>
整数子数组求最大和添加验证
查看>>
使用kubeadm安装Kubernetes
查看>>