重磅干货,第一时间送达正则表达式
背包问题是一个经典的动态规划模型。它既简单形象容易理解,又在某种程度上可以揭示动态规划的本质,故很多教材都把它做为动态规划部分的第一道例题.算法
彻底背包问题数组
有n个重量和价值分别为wi,vi的物品,从这些物品中挑选出总重量不超过W的物品,求全部挑选方案中价值总和的最大值
1≤n≤100
1≤wi,vi≤100
1≤W≤10000微信
输入:
整数用空格隔开 数据结构
第一行有两个整数N,V 表明物品种数和背包容积机器学习
接下来有N行,每行两个整数用空格隔开,表明物品体积和价值ide
输出:
在背包容量下可以最大化的价值函数
输入样例学习
4 6 1 1 2 3 3 4 4 5
输出样例:3d
9
与零一背包不一样的是,零一背包中的物品是不能够重复拿取的,只能够拿取当前物品或者不拿取当前物品,不能够拿取多个,彻底背包的物品是能够任意拿取多个的来构成不超过背包容量而且构成的总价值是最大的
动态规划的核心是找到dp公式或者状态转移的方程,理解清楚中间的过程是怎么样进行变化的,由于动态规划老是要利用到以前历史上的最佳方案,因此dp数组里面存储的确定是历史上存储的最佳方案,一开始的时候咱们是能够借助excel表格来帮助咱们理解dp数组是怎样生成的
咱们能够这样想:当前个人背包容量有多少,并且我能够选择的物品的范围是什么,那么这两个变量就能够肯定一个值了,咱们能够计算出当前背包容量对于当前能够选择的物品范围构成的最大价值
由输入可知第一个物品为1 1 即价值为1,所占的容量也为1。
根据f[i][j]=max(f[i][j-w[i]]+v[i])可知,从第一个物品开始,因为今天这个问题属于彻底背包问题,故两层循环中,第一层循环为遍历物品,第二层循环为从小到大扩大背包容量不断塞进更多的当前物品。
f[1][0]=max(f[1][0],f[1][0-1]+2) 不执行
执行 f[1][0]=f[0][0]
从上式能够知道我咱们取不到f[1][0-1] 故加个判断j>=w[i]便可,若知足就能够加入物品,不知足就不更新仍维持0
f[1][1]=max(f[1][1],f[1][1-1]+2)
f[1][2]=max(f[1][2],f[1][2-1]+2)
f[1][3]=max(f[1][3],f[1][3-1]+2)
f[1][4]=max(f[1][4],f[1][4-1]+2)
f[1][5]=max(f[1][5],f[1][5-1]+2)
这样第一个物品结束后,咱们来看看整个二维数组的更新状况
f[1][5]就表示了在选择第一个物品的时候,容量为5的状况下的最大价值为5
接下来更新第二个物品
加个判断j-w[i]>=0,若知足就能够加入物品,不知足就不更新仍维持0
f[2][0]=max(f[2][0],f[2][0-2]+3) 不执行
故执行f[2][0]=f[1][0]
f[2][1]=max(f[2][1],f[2][1-2]+3) 不执行
故执行f[2][1]=f[1][1]
f[2][2]=max(f[2][2],f[2][2-2]+3)
f[2][3]=max(f[2][3],f[2][3-2]+3)
f[2][4]=max(f[2][4],f[2][4-2]+3)
f[2][5]=max(f[2][5],f[2][5-2]+3)
这样第二个物品结束后,咱们来看看整个二维数组的更新状况
以此类推最后获得整个二维数组的状况为
1a=input() 2n, m=list(map(int, a.split())) 3w=[0 for i in range(n + 1)] 4v=[0 for i in range(n + 1)] 5f=[0 for i in range(m + 1)] 6for i in range(1, n + 1): 7 b=input() 8 w[i], v[i]=list(map(int, b.split())) 9 10for i in range(1, n + 1): 11 for j in range(1, m + 1): 12 if j >= w[i]: 13 f[j]=max(f[j], f[j - w[i]] + v[i]) 14 # 这个是考虑到能够选取多个物品的状况 15 16print(f[-1])
1int main(){ 2 int N,V; 3 cin>>N>>V; 4 vector<int> weight(N+1),value(N+1); 5 for(int i=1;i<=N;i++) 6 cin>>weight[i]>>value[i]; 7 vector<vector<int>> dp(N+1,vector<int>(V+1,0)); 8 for(int i=1;i<weight.size();i++){ 9 for(int j=0;j<=V;j++){ 10 11 dp[i][j]=dp[i-1][j]; 12 13 if(j-weight[i]>=0) 14 dp[i][j]=max(dp[i-1][j],dp[i][j-weight[i]]+value[i]); 15 } 16 } 17 cout<<dp[N][V]<<endl; 18} 19
2020大厂笔试 | 网易提早批(1)
2020大厂笔试 | 网易提早批(2)
使人头疼的背包九讲(1)0/1背包
剑指offer刷题交流群
扫码添加微信,必定要备注研究方向+地点+学校+昵称(如机器学习+上海+上交+汤姆),只有备注正确才能够加群噢。
▲长按加群