基础指南 之 背包问题

背包问题

背包问题是动态规划部分的代表部分,主要有 0-1 背包、完全背包等。

  1. 0-1 背包
    0-1背包中每种物品只有一件,故每种物品要么装进背包,要么没有装进背包,故曰 “0-1”。
    问题描述:n 种物品,每种物品只有一件,每种物品的重量为 wieght[i],每种物品的价值为 value[i] ,背包的总容量为 v ,求背包中能装入物品的最大价值总和。
    动态规划:dp[i][j] 表示背包容量剩下 j 时考虑装或者不装第 i 件物品的最大价值。
    状态转移方程:若 j < weight[i],此时背包容量无法装下物品 i ,则最大价值等于背包容量为 j 时考虑装或者不装物品 i-1 时的最大价值,即 dp[i][j]=dp[i-1][j];若 j>=weight[i],此时背包可以装下物品 i ,此时有两种选择,装下物品 i (但可能装不下 0到i-1之间的物品),或者不装物品 i ,即 dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])。程序如下所示:
void bag01()
{
    const int n;    //物品种类数
    const int w;    //背包最大容量
    int * weight[n+1]; //各物品重量
    int * value[n+1];  //各物品价值

    int dp[n+1][v+1];       //背包容量为v时选择装或者不装第n件物品的最大价值

    for (int i = 0; i < n+1; i++)
    {
        dp[i][0]=0;
    }
    for (int i = 0; i < v+1; i++)
    {
        dp[0][i]=0;
    }
    
    for (int i = 1; i < n+1; i++)
    {
        for (int j = 1; j < v+1; j++)
        {
            if(j<weight[i])
                dp[i][j]=dp[i-1][j];
            else
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
        }
    }
}

存储空间优化:
0-1背包中, dp[i][j]=max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]) ,新的物品装下或者不装的价值取决于 dp[i-1][j] 和 dp[i-1][j-weight[i]] ,dp[i-1][j] 在物品索引 i 的上一次循环中已计算出,而 dp[i-1][j-weight[i]] 是 i 的上一轮循环中计算出的,且在 j 的内层循环中,若将 j 的内层循环改成 从 v 到 0 的降序顺序,则 dp[i-1][j-weight[i]] 在 dp[i][j] 之前计算,而 dp[i][j-weight] 在dp[i][j] 之后计算,则可直接用 dp[j-weight] 来代替 dp[i][j-weight] ,只用一维的数据结构 dp[v] 来存储动态规划的状态。
状态转移方程:若 j >= weight[i] ,dp[j]=max(dp[j], dp[j-weight[i]]+value[i]),若 j < weight[i],则不更新 dp[i] 。
程序如下所示:

void bag01_opt()
{
    const int n;    //物品种类数
    const int w;    //背包最大容量
    int * weight[n+1]; //各物品重量
    int * value[n+1];  //各物品价值

    int dp[v+1];        //背包容量为v时最大价值

    //i=0初始化,利用只装第一件物品的情况初始化
    for(int j=0;j<=w;j++)
    {
        if(j<weight[0])
        {
            dp[j]=0;
        }
        else
        {
            dp[j]=value[0];
        }
    }

    //将 w 维度上的循环反序,保证计算dp[j]时的dp[j-weight[i]]是i-1轮循环保留下的,而不是i轮循环保存的
    //每个物品只有一件,故要保证 dp[j-weight[i]] 是i-1轮留下来的
    for(int i=1;i<n+1;i++)
    {
        for(int j=w;j>=weight[i];j--)
        {
            //此处不用判断,循环已经做了控制,大于才更行dp,小于不用更新
            dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
        }
    }
}
  1. 完全背包
    问题描述:n 种物品,每种物品有无数件,每种物品的重量为 wieght[i],每种物品的价值为 value[i] ,背包的总容量为 v ,求背包中能装入物品的最大价值总和。
    完全背包按照其思路可以用一个而为数组实现状态转移方程:
    f[i][j]=max{f[i-1][v-kweight[i]]+kvalue[i] | 0<=k && c[i]<=v};
    与0-1背包中原理类似,可将二维数组用一维数组表示:f[j]=max{f[j],f[j-weight[i]]+value[i] | j>=weight[i]};因为每种物品的数量无限,则无需保证 dp[j-weight[i]] 是 i 的哪一轮循环,则 j 的循环可以从 0 到 v ,程序如下所示:
void bag_full()
{
    const int n;    //物品种类数
    const int w;    //背包最大容量
    int * weight[n+1]; //各物品重量
    int * value[n+1];  //各物品价值

    int dp[v+1];        //背包容量为v时最大价值

    for(int i=0;i<n+1;i++)
    {
        dp[i]=0;
    }

    //每件物品有多件,故得保证dp[j-weight[i]]是当前考虑第i轮循环产生的最新结果
    for(int i=1;i<n+1;i++)
    {
        for(int j=0;j<V+1;j++)
        {
            //大于才更新dp
            if(j>=weight[i])
            {
                dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
            }
        }
    }
}
数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和教育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问题。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值