代码随想录打卡—day42—【DP】— 8.27 01背包基础

1 01背包基础

背包概述:

1.1 01背包是什么

有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

1.2 01背包二维数组

二维数组还比较好理解,五步法详见代码注释,AC代码:

#include<iostream>
using namespace std;const int N = 1e3 + 10;int weight[N];
int val[N];
int f[N][N];  // (i,j)表示只选取前i个商品 容积j的背包能够装的最大价值
/*if(j < weight[i])f[i][j] = f[i-1][j];  //装不下就只有不装一条路
else f[i][j] = max(f[i-1][j],f[i-1][j-weight[i]]+val[i]);  //装的下就有装和不装两种选择不装i       装i第0行--f[0][j]
for(int j = 0; j <= m ; j++)
{if(j >= weight[0])f[0][j] = val[0];else f[0][j] = 0;
}
第0列—— f[i][0]全设置为0顺序:先商品i后背包j(先背包后商品也行)*/int main()
{int n,m;cin >> n >> m;for(int i = 0; i < n; i++){int tmpw,tmpval;cin >> tmpw >> tmpval;weight[i] = tmpw;val[i] = tmpval;}//初始化for(int j = 0; j <= m ; j++)if(j >= weight[0])f[0][j] = val[0];else f[0][j] = 0;for(int i = 0; i <= n; i++)f[i][0] = 0;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)if(j < weight[i])f[i][j] = f[i-1][j];  //装不下就只有不装一条路else f[i][j] = max(f[i-1][j],f[i-1][j-weight[i]]+val[i]);  //装的下就有装和不装两种选择//  for(int i = 0; i <= n; i++)// {//     for(int j = 0; j <= m; j++)//     {//         cout << f[i][j] << ' ';//     }//     puts("");// }cout << f[n][m];return 0;
}

1.3 01背包一维数组(滑动数组)

滑动数组实质就是利用01背包二维数组版本中每个f[i][j]只会用到上一层左侧 f[i-1][j-xx] 的数据,所以把上一层左侧数据保存在当前行的左侧,并且每次在当前行内遍历时候从右往左边遍历。AC代码:

#include<iostream>
using namespace std;const int N = 1e3 + 10;int weight[N];
int val[N];
int f[N];  // (j)表示容积j的背包能够装的最大价值/*
转换方程:
if(j < weight[i])f[j] = f[j];  //装不下就只有不装一条路
else f[j] = max(f[j],f[j-weight[i]]+val[i]);  //装的下就有装和不装两种选择不装i       装i第0行--f[0] = 0;顺序:先商品i++后背包j--(j左边的作为上一层的记录),*/int main()
{int n,m;cin >> n >> m;for(int i = 0; i < n; i++){int tmpw,tmpval;cin >> tmpw >> tmpval;weight[i] = tmpw;val[i] = tmpval;}//初始化for(int i = 0; i <= n; i++)for(int j = m; j >= 0; j--)if(j < weight[i])f[j] = f[j];  //装不下就只有不装一条路else f[j] = max(f[j],f[j-weight[i]]+val[i]);  //装的下就有装和不装两种选择cout << f[m];return 0;
}

2 01背包应用题1——416. 分割等和子集

416. 分割等和子集

一开始看到题目,想用贪心——排序+双指针 每次都把当前相对小的放进小的sum中,写完之后发现过不了:[1,1,2,2]这样的样例。错误代码:

class Solution {
public:/*左边的sum 小于 右边的sum l++,左边的sum+=左边的sum 大于 同理如果等于左边前进 1,2,3,4, 5,6,7,8,9, 10*/bool canPartition(vector<int>& nums) {// 解法1:排序+双指针if(nums.size() == 1)return 0;sort(nums.begin(),nums.end());int l = 0;int r = nums.size() - 1;int leftsum = 0;int rightsum = 0;while(l <= r){if(leftsum <= rightsum){leftsum += nums[l++];}else{rightsum += nums[r--];}}cout << l << "  " << r << endl;cout << leftsum << "  " << rightsum;if(leftsum == rightsum)return 1;else return 0;}
};

要明确本题中我们要使用的是01背包,因为元素我们只能用一次。

回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。

那么来一一对应一下本题,看看背包问题如何来解决。

只有确定了如下四点,才能把01背包问题套到本题上来。

  • 背包的体积为sum / 2
  • 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素是不可重复放入。

具体分析过程见注释, AC代码:

class Solution {
public:// 找到一个背包 能够装nums.total(所有物体重量总和)/2的东西int dp[10005];    // 容积为i的背包 根据现有的物体重量情况最多能装的物体的重量/*转换成01背包问题:假设有一个nums.total/2的背包有若干个物体,每个物体的重量就是nums[i] 本题可以舍弃价值这个概念就是问一个nums.total/2的背包最多能够装的物体的重量是多少 能不能达到nums.total/2if(j < nums[i])dp[j] = dp[j];else dp[j] = max(dp[j] , dp[j - nums[i]]+nums[i]);dp[0] = 0;其他默认是0for物体i++ for容积j--模拟——*/bool canPartition(vector<int>& nums) {dp[0] = 0;int total = 0;for(auto i : nums)total += i;if(total % 2 == 0)total /= 2;else return 0;for(int i = 0; i < nums.size();i++){for(int j = total ; j >= 0; j--){if(j < nums[i])dp[j] = dp[j];else dp[j] = max(dp[j] , dp[j - nums[i]]+nums[i]);}}if(dp[total] == total)return 1;else return 0;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1619864.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

3D飞镖游戏源码ios版

一款ios 3D飞镖游戏源码,通过物理引擎和重力感应来控制飞镖向目标物体击中&#xff01;游戏比较简单&#xff0c;可以学习一下3D游戏的基本开发. 源码下载&#xff1a; http://code.662p.com/view/6262.html 开发平台&#xff1a; 在xcode 4.3编译通过&#xff0c;iphone4&am…

PS飞镖靶的制作

首先我们在Ps中新建一个600像素*600像素的画布&#xff0c;设置分辨率300/200都可以。 步骤如下&#xff1a; 1.拉出两条参考线&#xff0c;一条垂直居中&#xff0c;一条水平居中。 2.用椭圆工具在两参考线中心点拉出一个圆形&#xff0c;设置颜色红色。用矩形选框工具裁剪掉3…

[SCOI2011]飞镖[数学模拟]

2335: [SCOI2011]飞镖 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 482 Solved: 152[Submit][Status][Discuss] Description 飞镖是在欧洲颇为流行的一项运动。它的镖盘上分为20个扇形区域&#xff0c;分别标有1到20的分值&#xff0c;每个区域中有单倍、双倍和三倍的区…

【题解】[SCOI2011] 飞镖

模拟题 红靶子的我们先不考虑。 如果是 {1,2,2} &#xff0c; {2,2,3} 这种只涉及两种倍数的话&#xff0c;我们想到不定方程&#xff1a; axby c 的通解形式&#xff08;a,b,c 为常数&#xff09;&#xff0c;从而探讨 x,y 在规定取值内是否有解。 探讨 {1,2,3} 的情况。 …

搭载双筒飞镖?这款无人机太危险

折叠式的设计使之方便携带&#xff0c;堪称猎犬好搭档。 近日&#xff0c;基于SuperDrone无人机&#xff0c;南非Haevic公司改造了一款搭载飞镖枪的无人机——DartDrone&#xff0c;专为兽医及狩猎人员研发。 据悉&#xff0c;SuperDrone是一款采用可折叠结构的六翼无人机&…

BZOJ2335: [SCOI2011]飞镖

Description 飞镖是在欧洲颇为流行的一项运动。它的镖盘上分为20个扇形区域&#xff0c;分别标有1到20的分值&#xff0c;每个区域中有单倍、双倍和三倍的区域&#xff0c;打中对应的区域会得到分值乘以倍数所对应的分数。例如打中18分里面的三倍区域&#xff0c;就会得到54分。…

飞镖(bzoj 2335)

Description 飞镖是在欧洲颇为流行的一项运动。它的镖盘上分为20个扇形区域&#xff0c;分别标有1到20的分值&#xff0c;每个区域中有单倍、双倍和三倍的区域&#xff0c;打中对应的区域会得到分值乘以倍数所对应的分数。例如打中18分里面的三倍区域&#xff0c;就会得到54分。…

飞镖和招聘

4月16日 公司里面玩飞镖的同事越来越多了&#xff0c;不少人都得了飞镖综合症&#xff08;手酸、腰酸、对休息时间非常敏感&#xff09;。除了飞镖游戏本身的吸引力&#xff0c;我还发现它有很多和我们从事猎头 招聘非常相似的特征&#xff1a; Know how to close the game. 懂…

java设计飞镖游戏_3分钟手把手带你使用Unity制作“扔飞镖游戏”

原标题&#xff1a;3分钟手把手带你使用Unity制作“扔飞镖游戏” 日落西山红霞飞~战士打靶把营归呀巴扎嘿。今天我制作一个简单的打靶游戏(扔飞镖) 在制作之前首先要思考这个游戏需要什么对象&#xff0c;很简单&#xff0c;一只飞镖、一个靶。 这里我把飞镖设置成了刚体&#…

Leetcode——1453. 圆形靶内的最大飞镖数量

墙壁上挂着一个圆形的飞镖靶。现在请你蒙着眼睛向靶上投掷飞镖。 投掷到墙上的飞镖用二维平面上的点坐标数组表示。飞镖靶的半径为 r 。 请返回能够落在 任意 半径为 r 的圆形靶内或靶上的最大飞镖数。 示例 1&#xff1a; 输入&#xff1a;points [[-2,0],[2,0],[0,2],[0,-…

打印飞镖图形

打印如图下非标 代码如下 #define _CRT_SECURE_NO_WARNINGS #pragma warning(disable:6031) #include<stdio.h> #include<string.h> int main() {int n 0;while (scanf("%d", &n) 1){//上n行int i 0;for (i 0; i < n; i){int j 0;for (j 0…

【数据结构与算法】之深入解析“圆形靶内的最大飞镖数量”的求解思路与算法示例

一、题目要求 墙壁上挂着一个圆形的飞镖靶,现在请你蒙着眼睛向靶上投掷飞镖。投掷到墙上的飞镖用二维平面上的点坐标数组表示,飞镖靶的半径为 r,请返回能够落在任意半径为 r 的圆形靶内或靶上的最大飞镖数。示例 1:输入:points = [[-2,0],[2,0],[

【题解】飞镖

题目描述 小明喜欢玩飞镖游戏&#xff0c;他会把每次的得分都记录在数组中。今天有个飞镖大奖&#xff0c;得奖的规则是&#xff1a;如果你4次飞镖的得分先后是&#xff08;a&#xff0c;b&#xff0c;c&#xff0c;d&#xff09;&#xff0c;满足abcd。 小明准备把记录里的其他…

OpenCV技巧篇——多目标视觉定位(以飞镖定位为例)

OpenCV技巧篇【1】——多目标视觉定位&#xff08;以飞镖定位为例&#xff09; 1、针对问题 多目标视觉定位是指通过计算机视觉技术对一张图片中的多个目标进行识别和定位的过程。本篇将以对飞镖定位为例&#xff0c;提出一个简单有效的多目标定位技巧&#xff0c;最终实现如…

LeetCode 1453. 圆形靶内的最大飞镖数量(几何题)

1. 题目 墙壁上挂着一个圆形的飞镖靶。现在请你蒙着眼睛向靶上投掷飞镖。 投掷到墙上的飞镖用二维平面上的点坐标数组表示。飞镖靶的半径为 r 。 请返回能够落在 任意 半径为 r 的圆形靶内或靶上的最大飞镖数。 示例 1&#xff1a; 输入&#xff1a;points [[-2,0],[2,0…

一个飞镖模型

#飞镖 #一个角 from turtle import* def angle():pu()goto(0,0)pendown()pencolor("black")left(45)fd(50)left(68)fd(91.73)left(157)fd(120)begin_fill()fillcolor("black")right(135)fd(50)right(68)fd(91.73)right(157)fd(120)end_fill()#飞镖复杂化 d…

扔飞镖游戏

日落西山红霞飞~战士打靶把营归呀巴扎嘿。今天我制作一个简单的打靶游戏&#xff08;扔飞镖&#xff09; 在制作之前首先要思考这个游戏需要什么对象&#xff0c;很简单&#xff0c;一只飞镖、一个靶。 这里我把飞镖设置成了刚体&#xff0c;什么是刚体&#xff1f;简而言之&…

2022赛规整理——飞镖

2022赛规整理——飞镖 ​ V1.0 2021.10.23 1、比赛场地 &#xff08;1&#xff09;打击角度及距离 飞镖口——前哨站&#xff1a;左6.5&#xff0c;直线距离15865mm 飞镖口—— 基地 &#xff1a;右7.3&#xff0c;直线距离25233mm &#xff08;2&#xff09;基地示意图 基…

QT之“飞镖盘”自定义控件

QT之“飞镖盘”自定义控件 前言控件预览实现 前言 现在发一个我之前看过有人写了一个抽奖转盘&#xff0c;所以闲来无事写了一个飞镖盘控件&#xff0c;在我看来它其它没有什么实用价值&#xff0c;纯属写来玩玩而已。 控件预览 实现 画背景 void QDartboard::drawBkg(QPai…

在window上配置NASM

NASM是支持x86、x64架构CPU的汇编器(汇编软件)&#xff1b;NASM也支持大量的文件格式&#xff0c;包括Linux&#xff0c;*BSD&#xff0c;a.out&#xff0c;ELF&#xff0c;COFF&#xff0c;Mach−O&#xff0c;Microsoft 16−bit OBJ&#xff0c;Win32以及Win64&#xff0c;同…