首页 > 其他分享 >01背包

01背包

时间:2024-11-15 19:56:16浏览次数:1  
标签:01 const int 选法 背包 遍历 include dp

01背包

抽象出来是有n种物品,每种物品只可以选一个或则零个

如果爆搜的话会是\(2^n\),但利用\(dp\)可以减少不必要的讨论

模板

AcWing 2. 01背包问题 - AcWing

没什么好分析的,主要是二维向一维的优化,先看看朴素版本

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1005;
int v[MAXN];    // 体积
int w[MAXN];    // 价值 
int f[MAXN][MAXN];  // f[i][j], j体积下前i个物品的最大价值 

int main() 
{
    int n, m;   
    cin >> n >> m;
    for(int i = 1; i <= n; i++) 
        cin >> v[i] >> w[i];

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

    cout << f[n][m] << endl;

    return 0;
}

这里我们可以发现,每次更新\(f[i][j]\)的时候我们只利用到了上一层循环的值,换而言之在上一层之前的值没有意义,

所以我们可以利用滚动数组把二维优化为一维

要注意\(01\)背包的优化要反向遍历,因为假设我们从前往后遍历的话

$ f[i][j]$$=$ \(f[i-1][j]\)这项没有问题,但是当进行到\(f[i-1][j-v]+w\)的时候,利用的已经是先前更新过的这一层循环的值了

因此反向遍历可以避免这一点

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N];
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        int v,w;scanf("%d%d",&v,&w);
        for(int j=m;j>=v;j--)
        f[j]=max(f[j],f[j-v]+w);
    }
    
    cout<<f[m];
}

例题

278. 数字组合 - AcWing题库

题意很简单,从n个数字里选出总和恰好为\(m\)的总方案数

定义\(f[i][j]\)为从前\(i\)个物品里面选,总和恰好为\(j\)的方案数

状态划分为选择\(i\)与不选择\(i\),转移方程就显而易见了

\[f[i][j]=f[i-1][j]+f[i-1][j-a[i]] \]

#include<bits/stdc++.h>
using namespace std;
const int N=110,M=1e4+10;
int a[N];
int f[N][M];
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=0;i<=n;i++)f[i][0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            f[i][j]=f[i-1][j];
            if(j>=a[i])f[i][j]+=f[i-1][j-a[i]];
        }
    }
        cout<<f[n][m];
}

优化成一维,更新用上一层循环,所以是反向遍历

#include<bits/stdc++.h>
using namespace std;
const int N=110,M=1e4+10;
int f[M];
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    f[0]=1;
    for(int i=1;i<=n;i++)
    {
        int x;cin>>x;
        for(int j=m;j>=x;j--)
        {
            f[j]+=f[j-x];
        }
    }
        cout<<f[m];
}

上一题的扩展

Problem - D - Codeforces

有\(n\)种球,每种有若干个,每种球选或者不选,有\(2^n\)种选法

定义每种选法的\(value\)为把所选的每个球分在容量为\(2\)的组中,每组的颜色不可以相同的最小分法

假设选则的\(j\)种的球总和为\(sum\),最大值为\(mx\)

此种选法的\(vlaue\)为\(max(ceil(sum/2),mx)\)

如何使得可以遍历到每一种情况呢,可以这样考虑

用\(dp[i-1][j]\)表示从前\(i-1\)个物品中选,总和恰好等于\(j\)的选法,然后再选择\(a[i]\)

因为除了什么都不选之外,每种选法都是至少要选择一个\(a[i]\)的

从前往后遍历,固定一个a[i],考虑在前\(i-1\)个物品里选择再加上\(a[i]\)的选法,便是不重不漏的

为了方便计算,可以把数组先升序排序

#include <bits/stdc++.h>
using namespace std;
const int N=5010;
const int M=998244353;
long long dp[N][N];
int a[N];
int n;
void solve()
{
	dp[0][0]=1;
	scanf("%d",&n);
	int ans=0,m=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);m+=a[i];
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=m;j++)
		{
			if((j+1+a[i])/2>=a[i])ans=(ans+(j+a[i]+1LL)/2*dp[i-1][j])%M;
			else ans=(ans+1LL*a[i]*dp[i-1][j])%M;
			dp[i][j]=dp[i-1][j];
			if(j>=a[i])dp[i][j]=(dp[i][j]+dp[i-1][j-a[i]])%M;
		}
	}
	cout<<ans<<endl;
}
int main()
{
    int t=1;
    while(t--)solve();
}

标签:01,const,int,选法,背包,遍历,include,dp
From: https://www.cnblogs.com/NIYAXIMEN/p/18548571

相关文章

  • 2024-2025-1 20241401 《计算机基础与程序设计》 第八周学习总结
    班级链接2024计算机基础与程序设计作业要求第八周作业作业目标①功能设计与面向对象设计②面向对象设计过程③面向对象语言三要素④汇编、编译、解释、执行教材学习内容总结《计算机科学概论》第9章面向对象方法:介绍了面向对象(OOD)的基本概念,包括类和对......
  • PKUSC2018 最大前缀和
    题意给一个长度为\(n\)的整数序列,求其\(n!\)种排列方式的最大前缀和(不能为空)的总和。\(n\leq20\)解法设全集为\(U\),考虑枚举作为最大前缀和的子集\(S\)。那么要求的就是\(S\)排列后严格最大前缀和在最后一个元素取到和方案数和\(U\backslashS\)排列后每个前缀......
  • [AHOI2018初中组] 分组
    题目Description小可可的学校信息组总共有 nn 个队员,每个人都有一个实力值 aiai​。现在,一年一度的编程大赛就要到了,小可可的学校获得了若干个参赛名额,教练决定把学校信息组的 nn 个队员分成若干个小组去参加这场比赛。但是每个队员都不会愿意与实力跟自己过于悬殊的......
  • 国标GB28181-2016平台LiteGBS国标GB28181软件如何查看海康硬盘录像机NVR4.0lite的ip通
    随着视频技术的不断进步,视频监控、直播、执法记录仪等多种视频资源的应用场景愈发广泛且多样化。LiteGBS国标GB28181软件不仅在数量上快速增长,更在质量、格式及编码标准等方面展现出极高的多样性。因此,为了实现对这些资源的有效整合和统一管理输出,信息化项目中对于视频综合接入能......
  • 国标GB28181-2016平台LiteGBS国标GB28181视频平台球机安装好后发现云台不受控制的解决
    随着视频技术的不断进步,视频监控、直播、执法记录仪等多种视频资源的应用场景愈发广泛且多样化。LiteGBS国标GB28181视频平台不仅在数量上快速增长,更在质量、格式及编码标准等方面展现出极高的多样性。因此,为了实现对这些资源的有效整合和统一管理输出,信息化项目中对于视频综合接......
  • 201_springboot基于协同过滤的就业推荐系统
    目录系统展示开发背景代码实现项目案例 获取源码博主介绍:CodeMentor毕业设计领航者、全网关注者30W+群落,InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者,博客领航之星、开发者头条/腾讯云/AWS/Wired等平台优选内容创作者、深耕Web......
  • 在 Windows 中,RDP(远程桌面协议)默认使用 3389 端口。如果你想通过 PowerShell 更改此端
    在Windows中,RDP(远程桌面协议)默认使用3389端口。如果你想通过PowerShell更改此端口为10010,你需要修改注册表设置并重启远程桌面服务。以下是使用PowerShell更改RDP端口为10010的步骤:步骤:以管理员身份运行PowerShell。执行以下命令修改注册表,修改RDP端口设置:p......
  • 基于springboot+vue实现的大型超市数据处理系统 (源码+L文+ppt)4-015
      第4章 系统设计本章主要讲述的是大型超市数据处理系统的设计开发结构,简单介绍了开发流程与数据库设计的原则以及数据表的关系结构图,并且详细的展示了数据表的内部结构信息与属性。图4-2大型超市数据处理系统总体结构图4.4 数据表信息(共18张表)在关系数据E-R图中,......
  • 基于springboot+vue实现的高校电子图书馆的大数据平台 (源码+L文+ppt)4-013
      4.1系统结构设计这些功能可以充分满足高校电子图书馆的大数据平台的需求。此系统功能较为全面如下图系统功能结构如图4-1所示。图4-1功能结构图4.3.2 数据库表结构(共15张表)本论文中的高校电子图书馆的大数据平台采用MySQL数据库,系统中的所有对象以及对象的所有属性......
  • Exchange 2016部署实施案例篇-04.Ex基础配置篇(下)
    上二篇我们对全新部署完成的ExchangeServer做了基础的一些配置,今天继续基础配置这个话题。DAG配置先决条件首先在配置DGA之前我们需要确保DAG成员服务器上磁盘的盘符都是一样的,大小建议最好也相同。 其次我们需要确保有一块网卡用于数据复制使用(PS:单块网卡也可以......