背包

01背包

定义:

   有N件物品和一个容量为V的背包。每种物品只有一件,选或者不选,第i件物品的体积是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。

实现:

   令dp[i][j]表示选择前i件物品,背包体积为j时的最大价值。

   因为01背包中每件物品只有选和不选两种状态,所以状态方程比较容易实现:

   ①如果不放第i件物品,则dp[i][j]=dp[i-1][j]直接转移。

   ②如果放第i件物品,则dp[i][j]=dp[i-1][j-w[i]]+v[i]。

   可以看出,当背包容量小于当前物品体积时,只能放弃此物品。反之,可以选择放或不放。

 

 

 

   此方法的时间和空间复杂度都为O(N*V)。时间复杂度已经不能再优化了,但空间复杂度可以优化到O(V)

   可以看到,dp[i][j]的更新只涉及到dp[i-1][],也就是说dp[i][j]的更新只涉及到dp[][]数组中第(i-1)行,(i-1)行之前的数据就没有什么用了。

 

   

   可以看到dp[]数组降成了一维。与此同时需要注意的是,第二层循环成了逆序。因为旧方法中更新dp[i][]数组第i行时,dp[i-1][]的值都不会再改变了,如果第二层循环为顺序的话,那么在更新dp[j]时用到的dp[j-w[i]]在之前很可能已经被改变。所以为了保证在优化空间复杂度的同时保证正确性,把第二层循环改成逆序。

 

完全背包

定义:

   有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。

实现:

   令dp[i][j]表示选择前i种物品,背包体积为j时的最大价值。

   与01背包不同,现在物品都有无限件,所以完全背包的状态应该为取0件,取1件,取2件,……。可以得到01背包类似的状态转移方程:dp[i][j]=dp[i-1][j-k*w[i]]+k*v[i]。

   

    由于每件物品无限件,使得算法复杂度变大。

    那么如何实现优化呢?

    上面已经说过,01背包的优化之所以第二层循环是逆序根本目的就是保证每件物品只取一次。然而完全背包是每件物品取无限次,所以?

 

 

    与01背包优化算法唯一不同的就是第二层循环成了顺序。如果说01背包逆序是为了防止更新,那么完全背包顺序就是让它更新,以达到每件物品无限件的效果。

 

多重背包

定义:

   有N种物品和一个容量为V的背包。第i种物品最多有num[i]件可用,每件体积是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。

实现:

   多重背包的每种物品既不是一个也不是无限个,而是有限个。

    一.我们可以把多重背包直接当成01背包实现,只不过有的物品属性一样而已。在多重背包中,第一种物品有5件,可以任意取,那么在01背包中就是有5件 第一种物品,每件物品可以选或者不选。

    二.我们知道若干个数值为2^n的数相加可以表示一定范围内的所有数。

      进行组合,可以表示1-3;

      进行组合,可以表示1-7。

      这就是常说的多重背包二进制优化,我们可以利用这种思想去优化多重背包,然后利用01背包实现。

      如果我们第一种物品有3件,每件物品(体积为v,价值为w),那么二进制优化后,可以这样表达,我们有两件物品,第一件物品(v,w),第二件物品(2v,2w)。

      如果我们第一种物品有5件,每件物品(体积为v,价值为w),那么二进制优化后,可以这样表达,我们有三件物品,第一件物品(v,w),第二件物品(2v,2w),第三件物品(2v,2w)。

void Zero_onepack(int w,int v)
{
  for(int i=V;i>=w;i--)
    dp[i]=max(dp[i],dp[i-w]+v);
}
void Completepack(int w,int v)
{
  for(int i=w;i<=V;i++)
    dp[i]=max(dp[i],dp[i-w]+v);
}
void Multipack(int w,int v,int num)
{
  if(w*num>=V) Completepack(w,v); //这个物品可以直到取完,相当于完全背包
  else //二进制优化后01背包
   {
     int k=1;
     while(k<num)
     {
       Zero_onepack(k*w,k*v);
       num-=k;
       k<<=1;
     }
     Zero_onepack(num*w,num*v);
   }
}
View Code

 

分组背包:

定义:

   有N件物品和一个容量为V的背包。第i件物品的体积是w[i],价值是v[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。

实现:

   令dp[i][j]表示前i组物品,背包体积为j时的最大价值dp[i][j]。

   分组背包有两种状态,在一组中选一个或者一个都不选。那么状态转移方程为dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])。

   优化成一维,注意循环顺序:

                    for 所有的组k

                    for j=V..0

                     for 所有的i属于组k

                        dp[j]=max(dp[j],dpf[j-w[i]]+v[i])

 

此篇文章参考dd_engi的背包九讲。

转载于:https://www.cnblogs.com/VividBinGo/p/11363320.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园建设方案旨在通过融合先进技术,如物联网、大数据、人工智能等,实现校园的智能化管理与服务。政策的推动和技术的成熟为智慧校园的发展提供了基础。该方案强调了数据的重要性,提出通过数据的整合、开放和共享,构建产学研资用联动的服务体系,以促进校园的精细化治理。 智慧校园的核心建设任务包括数据标准体系和应用标准体系的建设,以及信息化安全与等级保护的实施。方案提出了一站式服务大厅和移动校园的概念,通过整合校内外资源,实现资源共享平台和产教融合就业平台的建设。此外,校园大脑的构建是实现智慧校园的关键,它涉及到数据中心化、数据资产化和数据业务化,以数据驱动业务自动化和智能化。 技术应用方面,方案提出了物联网平台、5G网络、人工智能平台等新技术的融合应用,以打造多场景融合的智慧校园大脑。这包括智慧教室、智慧实验室、智慧图书馆、智慧党建等多领域的智能化应用,旨在提升教学、科研、管理和服务的效率和质量。 在实施层面,智慧校园建设需要统筹规划和分步实施,确保项目的可行性和有效性。方案提出了主题梳理、场景梳理和数据梳理的方法,以及现有技术支持和项目分级的考虑,以指导智慧校园的建设。 最后,智慧校园建设的成功依赖于开放、协同和融合的组织建设。通过战略咨询、分步实施、生态建设和短板补充,可以构建符合学校特色的生态链,实现智慧校园的长远发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值