网易在线笔试牛牛的背包

2023-10-20 00:58

本文主要是介绍网易在线笔试牛牛的背包,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


        背包问题首先想到的就是动态规划了,但是这相当于遍历没一种可能性,当背包容量足够大,

零食种类足够多的时候就会出现超时的情况。

问题等价于   


其中, 表示第i个放入还是不放入, 设state(i,w)表示i个零食放入背包小于等于W的个数,把state(i,w)分解,可以分解为两个情况:
1、是第 i个不放入时,前i-1个零食放入背包小于等于W的种数即state(i-1,w);
2、是在第i个放入的情况下,前i-1个零食放入背包体积小于等于W-v[i]的个数即state(i-1,w-v[i]);
即               state(i,w) = state(i-1,w) + state(i-1,w-v[i])
边界条件:i = 1时,state(1,w1) 此时如果w1 >0 且v[1]<=w1,state(1,w1) = 2,即有可放入和不放入两种;
i = 1 时,swate(1,w1)此时如果w1 >0且v[1] > w1,state(1,w1)=1,即只有不放入一种;
如果state(i,w)中出现w<=0,则state(i,w)=0;
例子:零食体积1 2 4,w=10
则 state(3,10) = state(2,10) + state(2,6)
= state(1,10) + state(1,8) + state(1,6) + state(1,4)
= 2 + 2 + 2 + 2 = 8
采用递归解法:AC率80%。简简单单的代码实现如下


#include<iostream>
#include<vector>
using namespace std;int f(int n1, int n2,vector<int> &num)
{if(n2 <= 0){return 0;}if(n1 == 1){if(num[n1] <= n2){return 2;}else{return 1;}}return f(n1-1,n2,num) + f(n1 - 1,n2-num[n1],num);
}
int main()
{int n1,sum;cin >> n1 >> sum;vector<int> res(n1 + 1);for(int i=1;i<=n1;i++){cin >> res[i];}cout << f(n1,sum,res) << endl;                          return 0;
}
另一种思路是基于 DFS搜索的算法
#include <iostream>
#include <vector>
#include <cmath> //pow()函数头文件
using namespace std;
long long n, w;
vector<long long> good;
long long result = 0;
void dfs(int cur, long long sum)
{
if (sum <= w && cur == n)
result++;
if (cur == n || sum > w)
return;
dfs(cur + 1, sum + good[cur]);
dfs(cur + 1, sum);  //两次递归,相当于实现了选与不选,第二次是回溯的关键
}
int main() {
cin >> n >> w;
good.resize(n);
long long sum = 0;
for (int i = 0; i < n; i++) {
cin >> good[i];
sum += good[i];
}
if (sum <= w) {
//全部都可以放入
result = pow(2, n);
}
else {  //注意这里没加排序,加上会更好
dfs(0, 0);
}
cout << result << endl;
return 0;
}
​
//这个方法是别人的  DFS中看不到回溯,反正我是没看懂
#include<iostream>
#include<algorithm>
using namespace std;
long long nums = 1;
void DFS(vector<long long>& array, int size , long long w, long long sum, int pos){if(sum <= w){nums++;for(int i = pos + 1 ; i < size ; ++i) //问题就出现在这里{DFS(array,size,w,sum+array[i],i);}}
}
int main()
{int n;long long  w;cin >>n >> w;long long total = 0;vector<long long > array(n,0);for(int i = 0 ; i != n ; ++i){cin >> array[i];total += array[i];}if(total <= w){nums = pow(2,n);}else{sort(array.begin(),array.end()); //对数组进行排列,难道问题出现在这里?????? for(int i = 0 ; i != n ; ++i) //问题也出现在这里,这两个for循环DFS(array, array.size(), w, array[i],i);}cout<<nums<<endl;return 0;
}
#include <stdio.h>
#include <stack>
using namespace std;
struct TreeNode{int val;TreeNode *left;TreeNode *right;TreeNode (int x):val(x),left(NULL),right(NULL){}
};
// 非递归的后续遍历,另需要一个辅助指针
void preorder2(TreeNode *node)
{stack<TreeNode *> stack;TreeNode * p =node; //p是个工作指针TreeNode * pree ; //p是个前驱指针,记录访问过的节点int flag =1; while(p || !stack.empty()){while(p!=NULL)        {   //左子树一直入栈            stack.push(p);             //printf("[%d]\n",p->val);            p = p ->left;                   }         pree = NULL;         flag =1; //辅助变量为1表示当前节点的左孩子为空或者已经被访问过        while(!stack.empty() && flag==1)        {                    p =stack.top();             //如果右结点为空,或者左结点之前遍历过,打印根结点            if( p->right ==pree )            {            printf("[%d]\n",p->val);            pree = p;            stack.pop();            }            else //处理右孩子            {p = p -> right;             flag = 0; //*p的左孩子未被访问            }        }       }    }
int main()
{ TreeNode a(1); TreeNode b(2); TreeNode c(5); TreeNode d(3); TreeNode e(4); TreeNode f(6); a.left =&b; a.right =&c; b.left =&d; b.right =&e; c.right = &f; //preorder(&a,0); preorder2(&a); return 0;}




这篇关于网易在线笔试牛牛的背包的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/243551

相关文章

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

MySQL使用binlog2sql工具实现在线恢复数据功能

《MySQL使用binlog2sql工具实现在线恢复数据功能》binlog2sql是大众点评开源的一款用于解析MySQLbinlog的工具,根据不同选项,可以得到原始SQL、回滚SQL等,下面我们就来... 目录背景目标步骤准备工作恢复数据结果验证结论背景生产数据库执行 SQL 脚本,一般会经过正规的审批

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

csu(背包的变形题)

题目链接 这是一道背包的变形题目。好题呀 题意:给n个怪物,m个人,每个人的魔法消耗和魔法伤害不同,求打死所有怪物所需的魔法 #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>//#include<u>#include<map

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm