C/C++之01背包问题

2023-11-15

问题描述
  给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装M重量的背包.问怎么装使得所装价值最大.每个物品只有一个.
输入格式
  输入的第一行包含两个整数n, m,分别表示物品的个数和背包能装重量。
  以后N行每行两个数Wi和Vi,表示物品的重量和价值
输出格式
  输出1行,包含一个整数,表示最大价值。
样例输入
3 5
2 3
3 5
4 7
样例输出
8
数据规模和约定
  1<=N<=200,M<=5000.
第一种解法,先对背包通过重量排序,当重量不能放入的时候退出,主要方法是dfs+剪枝,但是超时了,可能是数据规模太大,效率不高导致超时

#include<iostream>
#include<algorithm>
using namespace std;
struct node{
	int weight;
	int value;
}arr[200];
int n,w;
int cmp(node n1,node n2)
{
	return n1.weight<n2.weight;
}
int _max=0;
void dfs(int weight,int index)
{
	if(index==n||weight<arr[index].weight)
	{
		if(value>_max)
			_max=value;
		return;
	}
	dfs(weight,value,index+1);
	dfs(weight-arr[index].weight,value+arr[index].value,index+1);
}
int main()
{
	cin>>n>>w;
	sort(arr,arr+n,cmp);
	for(int i=0;i<n;i++)
		cin>>arr[i].weight>>arr[i].value;
	dfs(w,0,0);
	cout<<_max;
}

第二种解法dfs,其实和第一种解法感觉差不多,但是通过结果来看,好像比第一种效果更好,不过还是难逃超时

#include<iostream>
using namespace std;
int w[1000];
int v[1000];
int n;
int W;
int dfs(int i,int ww)
{
	int ans;
	if(ww<=0)
		return 0;
	if(i==n)
		return 0;
	int v2=dfs(i+1,ww);
	if(ww>=w[i])
	{
		int v1=v[i]+dfs(i+1,ww-w[i]);
		ans= max(v1,v2);
	}
	else
		ans= v2;
	return ans;
}
int main()
{
	cin>>n>>W;
	for(int i=0;i<n;i++)
	{
		cin>>w[i]>>v[i];
	}
	int ww=W;
	cout<<dfs(0,ww);	
}

第三种解法,是第二种的剪枝,采用记忆的方法实现剪枝

#include<iostream>
using namespace std;
int w[1000];
int v[1000];
int n;
int W;
int dp[1000][1000];
int dfs(int i,int ww)
{
	int ans;
	if(ww<=0)
		return 0;
	if(i==n)
		return 0;
	if(dp[i][ww]>0)
		return dp[i][ww];
	int v2=dfs(i+1,ww);
	if(ww>=w[i])
	{
		int v1=v[i]+dfs(i+1,ww-w[i]);
		ans= max(v1,v2);
	}
	else
		ans= v2;
	dp[i][ww]=ans;
	return ans;
}
int main()
{
	cin>>n>>W;
	for(int i=0;i<n;i++)
	{
		cin>>w[i]>>v[i];
	}
	int ww=W;
	cout<<dfs(0,ww);	
}

第四种解法,通过迭代求解,主要通过二维数组记录当前节点的最大价值,然后一步步迭代,最终求得结果

#include<iostream>
using namespace std;
int n,w;
int weight[5010];
int value[300];
int dp[300][5010];
int main()
{
	cin>>n>>w;
	for(int i=1;i<=n;i++)
		cin>>weight[i]>>value[i];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=w;j++)
			if(j>=weight[i])
			{
				dp[i][j]=max(dp[i-1][j],value[i]+dp[i-1][j-weight[i]]);
			}
			else
				dp[i][j]=dp[i-1][j];
	cout<<dp[n][w];
	return 0;
}

完全背包

可重复

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
 
int n,m;
int w[5010],v[5010];
int dp[5010][5010];
 
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d",&w[i],&v[i]);
        }
        for(int i=1; i<=n; i++)//数量;
        {
            for(int j=0; j<=m; j++)//背包能放的重量;
            {
                if(j<w[i])//放不下;
                    dp[i][j]=dp[i-1][j];
                else//可以放下,就有放和不放两种选择;
                    dp[i][j]=max(dp[i-1][j],v[i]+dp[i][j-w[i]]);
            }
        }
        printf("%d\n",dp[n][m]);
    }
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++之01背包问题 的相关文章

  • SpringBoot中运行测试:java.lang.NullPointerException

    问题展示 SpringBoot中运行测试类报 java lang NullPointerException 问题描述 提示 这里描述项目中遇到的问题 在SpingBoot中当我们在它原有的测试基类BaseSpringBootTest jav
  • 7年经验之谈 —— 如何高效的开展app的性能测试?

    APP性能测试是什么 从网上查了一下 貌似也没什么特别的定义 我这边根据自己的经验给出一个自己的定义 如有巧合纯属雷同 客户端性能测试就是 从业务和用户的角度出发 设计合理且有效的性能测试场景 制定各性能场景下的客户端性能指标 内存 CPU

随机推荐

  • 微信小程序服务器域名怎么填,微信小程序合法域名配置方法

    在微信小程序的开发过程中 当需要请求第三方网站数据时 各种教程就直接说调用wx request接口即可 但是当初学者自己用的时候就会出现问题 比如我们这里请求聚合数据的API 里边有不少免费的数据申请就可以使用 调用邮编查询的接口 getP
  • Mybatis嵌套查询与嵌套结果

    一对多关系 一是用户 多是订单 实体类User public class User private Integer id private String name private Integer age private List
  • 后台获取前端提交数据的GET、POST方法遇到的问题

    在写代码的时候 总发现前端数据获取不到 最后发现了问题是因为get和post要一起出现 缺一不可 protected void doGet HttpServletRequest request HttpServletResponse res
  • JavaWeb之添加数据,显示到页面

    需求 从jsp页面添加一条记录到数据库 且显示到界面 分析 创建jsp页面 创建EmailServlet gt addEmail方法 设置请求编码 获取所有parameter的值 封装对象 调用addEmail方法 重定向到email sh
  • 游戏开发unity杂项知识系列:SetActive使用注意

    static public void SetActive GameObject go bool state if go null return if go activeSelf state go SetActive state 项目中类似上
  • JSP语法:setProperty

    JSP语法 13 setProperty 时间 2009 03 21 20 37 来源 作者 CSDN IE QQ 百度 Google POCO 新浪 365Key 天极 和讯 博拉 Live 奇客 收客 饭否 叽歪
  • 互联网未来发展方向

    都知道马云带来了互联网以及互联网的高潮 随着国家推动一带一路经济带 以及国内互联网大局的发展 很明显未来是互联网的天下 而互联网将来会怎样哪 第一 网购或者终端购物成为主流 随着经济发展 社会文明进步 智能制造 智能社会越来越凸显 智能手机
  • Python和C语言哪个难?零基础学哪个好?

    Python和C语言哪个难 零基础学哪个好 Python上手简单有交互性强的开发环境 还有众多的第三方库 学习起来会比C C 容易的多 C过于底层强在内存操作 功能实现起来却十分复杂并不适合新手作为上手语言 Python和C语言各有各的优势
  • Elastic Search 学习笔记

    来自尚硅谷 ES 教程 背景知识 从MySQL 到 ES 这一小节是我的一点点理解 如果有不对的话 欢迎指正 ES 是一个开源的高扩展的分布式全文搜索引擎 这样讲似乎还是有点抽象 那我们用一个更加熟悉的东西 MySQL来辅助理解 既然是搜索
  • 程序员技术面常用知识点

    转自 http blog csdn net qq 15437629 article details 52388685 在这里只做备份 计算机网络 TCP IP 模型 TCP IP协议集的分层实施 为什么要给网络划分层次 1 各层之间相对独立
  • 接口(interface)的实现

    接口 interface 的实现 usb插槽就相当于现实中的接口 其实现实生活和编程相对应的 即程序就是事件 1 java中的接口是怎么实现的呢 接口就是给出一些没有实现的方法 到了某个类要使用的时候就去实现他 语法 interface 接
  • Python多层字典取值

    usr bin python coding utf 8 author Bingo he file get target value py time 2017 12 22 def get target value key dic tmp li
  • 对于vue项目整理增删改查

    模板是来源于官方文档 清除tabledata里的模拟数据先
  • Pytorch相关操作(2)

    PyTroch相关操作 1 21 torch cuda Event 记录GPU的运行时间 start torch cuda Event enable timing True end torch cuda Event enable timin
  • Android Handler 的基本使用

    1 前言 https developer android google cn reference android os Handler html Handler 是 Android 中线程通信的常用方式 文档如是说 A Handler al
  • 【从零开始学c++】——string

    学好STL 一 STL简介 了解 1 什么是STL 2 STL的六大组件 3 STL的缺陷 2 string 1 string的简单了解 如何对stl的查阅 2 string常用接口说明 1 string类 对象常见的构造 2 string
  • Kotlin入门学习(非常详细),从零基础入门到精通,看完这一篇就够了

    文章目录 kotlin的历史 Kotlin的工作原理 语言类型 编译型 解释型 Java的语言类型 Kotlin的运行原理 创建Kotlin项目 语法 变量 变量的声明 基本类型 var和val的本质区别 函数 函数的声明 声明技巧 函数的
  • 找准边界,吃定安全

    创新的资源管理算法 基于会话的全分布式处理流程 山石网科全分布式架构 打破了传统架构的限制 找准边界 吃定安全 往期文章 从访问控制谈起 再看零信任模型 威胁情报加持 泛边界下的全局主动防御体系如何着手 随着 2019 年我国以信息网络等新
  • 连 连 看

    1 案例介绍 连连看是一款曾经非常流行的小游戏 游戏规则 点击选中两个相同的方块 两个选中的方块之间连接线的折点不超过两个 接线由X轴和Y轴的平行线组成 每找出一对 它们就会自动消失 连线不能从尚未消失的图案上经过 把所有的图案全部消除即可
  • C/C++之01背包问题

    问题描述 给定N个物品 每个物品有一个重量W和一个价值V 你有一个能装M重量的背包 问怎么装使得所装价值最大 每个物品只有一个 输入格式 输入的第一行包含两个整数n m 分别表示物品的个数和背包能装重量 以后N行每行两个数Wi和Vi 表示物