当前位置: 首页 > wzjs >正文

济南做网站建设的公司广州谷歌seo公司

济南做网站建设的公司,广州谷歌seo公司,极简wordpress,网站地图样式目录 01背包问题滚动数组优化(二维-->一维) 完全背包问题优化 多重背包二进制优化 感悟 动态规划 总而言之,就是利用 历史记录, 避免重复计算。 1.确定状态变量(函数) 2.确定状态转移方程 3.确定边界条…

目录

  • 01背包问题
    • 滚动数组优化(二维-->一维)
  • 完全背包问题
    • 优化
  • 多重背包
    • 二进制优化
  • 感悟

动态规划 总而言之,就是利用 历史记录避免重复计算

1.确定状态变量(函数)
2.确定状态转移方程
3.确定边界条件

首先我们要有一个状态数组,弄清楚它的状态表示,所谓状态表示,就是这个数组f(i,j)所代表的是什么,就背包而言,它代表的是一个集合,集合中所有选法满足相应条件最优解.这个最优解可能物体的某个属性,可以是最大值,最小值,数量等等。
其次就是状态的计算,也就是集合的划分,找到关系数组之间的关系式

01背包问题

  • 01背包
    每件物品只有一个(只能用一次)

在这里插入图片描述
以此题为例
用 i 记录物品数量,j 表示当前状态背包容量,那么函数数组f[i][j]表示的就是前i件物品放入容量为j的背包最大价值.最终的最大价值就是i为n,j为m时的**f[n][m]**的值。
下面要推导状态转移方程,分两种情况,第i件物品放入和不放入。

  • 如果放入,那么背包容量要减少Wi,同时价值增加Ci.
  • 如果不放入,那么背包容量还是j不变,并且没有价值增加
    -取二者的最大值,就是相应的f[i][j]

那么状态转移方程为:

f [ i ] [ j ] = = { 放入 i : f [ i ] [ j ] = f [ i − 1 ] [ j − W i ] + C i 不放入 i :  f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j]= =\left\{ \begin{matrix} \ 放入i:f[i][j]=f[i-1][j-Wi]+Ci \\ 不放入 i: \ f[i] [j]\ =\ f[i-1][j] \end{matrix} \right. f[i][j]=={ 放入i:f[i][j]=f[i1][jWi]+Ci不放入i f[i][j] = f[i1][j]
推导出:f[i][j]=max(f[i-1][j],f[i-1][j-Wi]+Ci)
边界条件:f[i][j]=0

#include<bits/stdc++.h>
using namespace std;
const int N=205; 
int n,m,f[N][N],w[N],c[N];
int main()
{cin>>n>>m;for(int i=1;i<=n;i++)cin>>w[i]>>c[i];for(int i=1;i<=n;i++)for(int j=0;j<=m;j++){f[i][j]=f[i-1][j];//这种情况一定存在 if(j>=w[i])//这种情况可能存在 f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i]);}cout<<f[n][m]; return 0;
}

滚动数组优化(二维–>一维)

上面的10~16行可替换为:

for(int i=1;i<=n;i++)
{for(int j=m;j>=w[i];j--){f[j]=max(f[j],f[j-w[i]]+c[i]);}
}

完全背包问题

  • 完全背包
    每件物品有无限个

在这里插入图片描述
可以看到01背包和完全背包的区别是

  • 01背包:第i件物品可以放入0个或1个
  • 完全背包:第i件物品可以放0,1,2,3…个(多个)

因此状态计算有所改变。
但是,f[i][j]表示的仍然是前i件物品放入容量为j的背包最大价值
同样是分两种情况,放i和不放i

  • 如果不放入,i值不变,j也不变,f[i][j]=f[i-1][j]
  • 如果放入,i还是i,这就是和01背包的区别啦,因为对于前i件物品,可能已经放入了第i件物品,容量为j时还能再放入第i件物品,那么f[i][j]=f[i][j-w[i]]+c[i].

那么状态转移方程为:

f [ i ] [ j ] = = { 放入 i : f [ i ] [ j ] = f [ i ] [ j − W i ] + C i 不放入 i :  f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j]= =\left\{ \begin{matrix} \ 放入i:f[i][j]=f[i][j-Wi]+Ci \\ 不放入 i: \ f[i] [j]\ =\ f[i-1][j] \end{matrix} \right. f[i][j]=={ 放入i:f[i][j]=f[i][jWi]+Ci不放入i f[i][j] = f[i1][j]
推导出:f[i][j]=max(f[i-1][j],f[i][j-Wi]+Ci)
边界条件:f[i][j]=0

#include<bits/stdc++.h>
using namespace std;
const int N=205;
int f[N][N],w[N],c[N];
int main()
{int n,m;cin>>n>>m;for(int i=1;i<=n;i++)cin>>w[i]>>c[i];for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(j<w[i])f[i][j]=f[i-1][j];elsef[i][j]=max(f[i-1][j],f[i][j-w[i]]+c[i]);}cout<<f[n][m];return 0;
}

上面的做法时间复杂度为O(nm)空间复杂度也为O(nm)
能否优化呢?答案是能!

优化

无法优化时间复杂度,但可以优化空间,我们可以直接让f[j]记录一行的数据,因为是顺序循环f[j-w[i]]会比f[j]先更新出来,继而可以利用f[j-w[i]]更新出新的f[j]的值。
上面11~18行可以优化为:

for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{f[j]=max(f[j-w[i]]+c[i],f[j]);
}

多重背包

  • 多重背包
    每个物品有有限个(有个数限制)
    在这里插入图片描述
    那么01背包和多重背包的区别是:
  • 01背包:第i件物品可以放入0个或1个
  • 多重背包:第i件物品可以放0,1,2,3…s[i]个(有限个)

暴力写法(三重循环)
暴力来写我们就可以通过枚举,考虑每种情况,在条件的限制下,求得相应的f[i][j].
将多重转化为01:只需把第i件物品换成s[i]件01背包中的物品,那么每件物品的体积为j*v[i],价值为k*w[i].
类比01

for(int i=1;i<=n;i++)
{for(int j=m;j>=v[i];j--)f[j]=max(f[j],f[j-v[i]]+w[i]);
}

转换后:

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n,m,f[N][N],v[N],w[N],s[N];
int main()
{cin>>n>>m;for(int i=1;i<=n;i++)cin>>v[i]>>w[i]>>s[i];for(int i=1;i<=n;i++)for(int j=0;j<=m;j++)for(int k=0;k<=s[i]&&k*v[i]<=j;k++)f[i][j]=max(f[i][j],f[i-1][j-v[i]*k]+w[i]*k);cout<<f[n][m];return 0;
}

将多重转化为01:只需把第i件物品换成s[i]件01背包中的物品,那么每件物品的体积为j*v[i],价值为k*w[i].
上面10~13行可以改为:

这题给的范围较小,但如果范围很大呢?我们又该如何优化呢?

二进制优化

二进制拆分思想:

如果我们将每i种物品的数量s[i]再拆分成一些数(转换为2的幂次数,这样就能的到每一个数),每次装进分好的系数个,并且每件物品的体积和价值都要乘以这个系数,就可以将多重背包真正的转化为01背包求解。
例如:
si=12.
拆分系数分别为:1,2,4,5;
这样就转化为4 个01 背包的物品
即:
(vi,wi),(2vi,2wi),(4vi,4wi),(5vi,5wi)

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n,m,f[N],v[N],w[N],v1,w1,s1;
int main()
{cin>>n>>m;int ans=1;for(int i=1;i<=n;i++){cin>>v1>>w1>>s1;//初值for(int j=1;j<=s1;j*=2){v[ans]=j*v1;w[ans]=j*w1;ans++;s1-=j;}if(s1)//如果有剩余{v[ans]=s1*v1;w[ans]=s1*w1;ans++;}}for(int i=1;i<ans;i++){for(int j=m;j>=v[i];j--)f[j]=max(f[j],f[j-v[i]]+w[i]);}cout<<f[m];return 0;
}

感悟

辛苦你看到了最后~相信你一定会有所收获,另外,就算你学下来有点吃力,有点困难,也不要灰心丧气,我认为对我们初学者来说,动态规划是有点难理解,需要大家好好动下脑筋,然而不能因为一时学不会就妄自菲薄,认为自己不行,我们都要相信自己,如果学的慢学的费劲,也不要焦虑,我们并非天才,那就慢慢来,一步一个脚印。
既然写到了这里,我也不禁感叹一下,最近在大学语文种学的一首诗–《秋声赋》。里面有这两句“奈何以非金石之质,欲与草木而争荣” , 以及“百忧感其心,万事劳其形”。

我们常常为了追求功名与利禄而奔波忙碌,忽略了身边的美好,也忘记了倾听内心的声音。我们总是担心错过机会,害怕落后于人,责备自己不够优秀,于是在无尽的焦虑和压力种迷失了自我。然而我们应调整自己的心态,欣然面对每一件事,不必盲目与他人相比,别人两小时学会的东西,你两个星期能学会,那你就是好样的!不必过分纠结力所不能及之事。加油o~

http://www.dtcms.com/wzjs/131684.html

相关文章:

  • 最新的网站建设软件外贸网站建设设计方案
  • 网站首页布局设计教程网站策划报告
  • 做赌钱网站手机网站自助建站系统
  • 河西做网站的公司企业营销平台
  • html网站开发心得莆田seo推广公司
  • 武汉企业网站建设的公司潍坊网站开发公司
  • 我想建网站百度爱采购怎样入驻
  • 电商网站的对比简单免费制作手机网站
  • 吉林市网站制作新手学百度竞价要多久
  • 宁波市网站制作seo工作内容
  • 网站做优化需要多少钱在线外链
  • 网站建设售后完善产品怎么进行推广
  • 网站建设开发案例网站流量分析
  • 怎样做二维码链接到网站上百度投票人气排行榜入口
  • 乒乓球网站建设目标小程序开发教程
  • 网站公安备案 工信备案本周新闻热点
  • 无锡营销型网站制作东莞企业推广网站制作
  • 网络运营平台济南网站优化排名推广
  • 江西省建设厅教育网站上查询郑州网站运营
  • 网站建设优化安徽百度推广投诉中心
  • 企业商标图片大全班级优化大师是干什么用的
  • 做网站要招什么样的程序员电脑培训网上免费课程
  • b站做视频哪个网站收入怎么做网页
  • 深圳有哪些物流公司windows优化大师绿色版
  • 伤豆丁文库网站开发淘宝优秀软文范例100字
  • 如何开发cms网站网站排名优化专业定制
  • qq网站官网网站服务器一年的费用
  • 建设厅网站上保存键看不见网页模板建站系统
  • 纵横互联 武汉网站建设网络营销的手段包括
  • 大兴网站建设报价广州市口碑seo推广