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

济南做门户网站开发公司/百度seo优化推广

济南做门户网站开发公司,百度seo优化推广,凡客网站建站教程,网站添加qq客服代码背包问题是动态规划中最经典的问题,很多题⽬或多或少都有背包问题的影⼦。它的基本形式是:给定⼀组物品,每个物品有体积和价值,在不超过背包容量的情况下,选择物品使得总价值最⼤。 背包问题有多种变体,主要…

背包问题是动态规划中最经典的问题,很多题⽬或多或少都有背包问题的影⼦。它的基本形式是:给定⼀组物品,每个物品有体积和价值,在不超过背包容量的情况下,选择物品使得总价值最⼤。
背包问题有多种变体,主要包括:

  1. 01背包问题:每种物品只能选或不选(选0次或1次)。
  2. 完全背包问题:每种物品可以选择⽆限次。
  3. 多重背包问题:每种物品有数量限制。
  4. 分组背包问题:物品被分为若⼲组,每组只能选⼀个物品。
  5. 混合背包:以上四种背包问题混在⼀起。
  6. 多维费⽤的背包问题:限定条件不⽌有体积,还会有其他因素(⽐如重量)。

除了经典的总价值最⼤问题,还会有:

  1. ⽅案总数。
  2. 最优⽅案。
  3. ⽅案可⾏性。
  4. 输出具体⽅案。
01背包

我们先解决第⼀问:

  1. 状态表⽰:
    dp[i][j]表⽰:从前i个物品中挑选,总体积「不超过」j,所有的选法中,能挑选出来的最⼤
    价值。
    那么dp[n][v]就是我们要的结果。
  2. 状态转移⽅程:
    线性dp 状态转移⽅程分析⽅式,⼀般都是根据「最后⼀步」的状况,来分情况讨论:
    a. 不选第i个物品:相当于就是去前i-1个物品中挑选,并且总体积不超过j。此时dp[i][j] = dp[i - 1][j]
    b. 选择第i个物品:那么我就只能去前i-1个物品中,挑选总体积不超过j-v[i]的物品。
    此时dp[i][j] = dp[i - 1][j - v[i]] + w[i]。但是这种状态不⼀定存在,因此需要特判⼀下。
    综上,状态转移⽅程为:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i])
  3. 初始化:
    直接填表,第⼀⾏的0 不影响结果。
  4. 填表顺序:
    根据「状态转移⽅程」,我们仅需「从上往下」填表即可
#include <bits/stdc++.h>
using namespace std;const int N = 1010;int n, m;
int v[N], w[N];
int f[N][N];int main()
{ios::sync_with_stdio(false);cin.tie(0);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 = 0; j <= m; j++){f[i][j] = f[i-1][j];if (j >= v[i]){f[i][j] = max(f[i][j], f[i-1][j-v[i]] + w[i]);}}}cout << f[n][m] << endl;return 0;
}

接下来解决第⼆问:
第⼆问仅需修改⼀下初始化以及最终结果即可。

  1. 初始化:
    因为有可能凑不⻬j体积的物品,因此我们把不合法的状态设置为负⽆穷。这样在取最⼤值的时候,就不会考虑到这个位置的值。负⽆穷⼀般设置为-0x3f3f3ff3即可。
    然后把dp[0][0] = 0修改成0,因为这是⼀个合法的状态,最⼤价值是0 ,也让后续填表是正确
    的。
  2. 返回值:
    在最后拿结果的时候,也要判断⼀下最后⼀个位置是不是⼩于0 ,因为有可能凑不⻬。
    不能判断是否等于-0x3f3f3f3f,因为这个位置的值会被更新,只不过之前的值太⼩,导致更
    新后还是⼩于0的
#include <bits/stdc++.h>
using namespace std;const int N = 1010;int n, m;
int v[N], w[N];
int f[N][N];int main()
{ios::sync_with_stdio(false);cin.tie(0);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 = 0; j <= m; j++){f[i][j] = f[i-1][j];if (j >= v[i]){f[i][j] = max(f[i][j], f[i-1][j-v[i]] + w[i]);}}}cout << f[n][m] << endl;memset(f, -0x3f, sizeof f);f[0][0] = 0;for (int i = 1; i <= n; i++){for (int j = 0; j <= m; j++){f[i][j] = f[i-1][j];if (j >= v[i]){f[i][j] = max(f[i][j], f[i-1][j-v[i]] + w[i]);}}}if (f[n][m] < 0) cout << 0 << endl;else cout << f[n][m] << endl;return 0;
}

空间优化:

  1. 考虑是否要修改遍历顺序
  2. 直接在原始代码上,删掉第一维即可
#include <bits/stdc++.h>
using namespace std;const int N = 1010;int n, m;
int v[N], w[N];
int f[N];int main()
{ios::sync_with_stdio(false);cin.tie(0);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 = m; j >= v[i]; j--){f[j] = max(f[j], f[j-v[i]] + w[i]);}}cout << f[m] << endl;memset(f, -0x3f, sizeof f);f[0] = 0;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]);}}if (f[m] < 0) cout << 0 << endl;else cout << f[m] << endl;return 0;
}
P1048 [NOIP 2005 普及组] 采药 - 洛谷

基本01 背包问题,将时间看成体积,就是标准的不放满的01 背包问题

#include <bits/stdc++.h>
using namespace std;const int N = 1010;int n, m;
int t[N], w[N];
int f[N][N];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> m >> n;for (int i = 1; i <= n; i++) cin >> t[i] >> w[i];for (int i = 1; i <= n; i++){for (int j = 0; j <= m; j++)        {f[i][j] = f[i-1][j];if (j >= t[i]) f[i][j] = max(f[i][j], f[i-1][j-t[i]] + w[i]);}}cout << f[n][m] << endl;return 0;
}

空间优化:

#include <bits/stdc++.h>
using namespace std;const int N = 1010;int n, m;
int t[N], w[N];
int f[N];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> m >> n;for (int i = 1; i <= n; i++) cin >> t[i] >> w[i];for (int i = 1; i <= n; i++){for (int j = m; j >= t[i]; j--)        {f[j] = max(f[j], f[j-t[i]] + w[i]);}}cout << f[m] << endl;return 0;
}
P1164 小A点菜 - 洛谷

背包问题求⽅案数,稍微修改⼀个状态表⽰,然后根据具体问题分析状态转移⽅程和初始化即可。

  1. 状态表⽰:
    dp[i][j]表⽰:从前i 个菜中挑选,总价钱恰好等于j ,此时的总⽅案数。
  2. 状态转移⽅程:
    针对a[i]选或者不选,分两种情况讨论:
    a. 如果不选a[i]:相当于去前i-1个菜中挑选,总价钱恰好为j的⽅案数,此时的⽅案数就
    dp[i - 1][j]
    b. 如果选a[i]:那么应该去前i-1个菜中挑选,总价值恰好为j-a[i],此时的⽅案数就是dp[i - 1][j - a[i]]
    因为我们要的是总⽅案数,于是dp[i][j] = dp[i - 1][j] + dp[i - 1][j - a[i]]
    注意第⼆个状态可能不存在,要注意判断⼀下j ≥ a[i]
  3. 初始化:
    dp[0][0],如果没有物品,想凑成总体积为0是可⾏的,啥也不选就是⼀种⽅案。当然,这个状态也是为了让后⾯的值是正确的。
    其余位置的值是0 就不影响填表的正确性。
  4. 填表顺序:
    从上往下每⼀⾏,每⼀⾏从左往右。
    空间优化版本:每⼀⾏从右往左
#include <bits/stdc++.h>
using namespace std;const int N = 110, M = 10010;int n, m;
int a[N];
int f[N][M];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= n; i++) cin >> a[i];f[0][0] = 1;for (int i = 1; i <= n; i++){for (int j = m; j >= 0; 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] << endl;return 0;
}

空间优化:

#include <bits/stdc++.h>
using namespace std;const int N = 110, M = 10010;int n, m;
int a[N];
int f[M];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= n; i++) cin >> a[i];f[0] = 1;for (int i = 1; i <= n; i++){for (int j = m; j >= a[i]; j--){f[j] += f[j-a[i]];}}cout << f[m] << endl;return 0;
}
P2946 [USACO09MAR] Cow Frisbee Team S - 洛谷

01 背包问题变形。

  1. 状态表⽰:
    dp[i][j]表⽰:从前i 头奶⽜中挑选,总和模f 之后为j 时,⼀共有多少种组合。
    那么dp[n][0] - 1就是最终结果。(因为动态规划会把全都不选这种情况也考虑进去,所以要剪掉)
  2. 状态转移⽅程:
    对于第i 头奶⽜选或者不选,可以分为两种情况讨论:
    a. 如果不选a[i]:此时的总⽅案数就是去[1, i - 1]⾥⾯凑余数正好是j ,也就是dp[i - 1][j]
    b. 如果选a[i] :此时已经有⼀个余数为a[i] % f,只⽤再去前⾯凑⼀个j - a[i] % f即可。但是直接减可能会减出来⼀个负数,我们要把它补正,最终凑的数为(j - a[i] % f + f) % f
    那么总⽅案数就是dp[i - 1][(j - a[i] % f + f) % f]
    因为要的总⽅案数,所以状态转移⽅程就是上⾯两种情况的总和。
  3. 初始化:
    dp[0][0] = 1:什么也不选的时候,总和是0 ,余数也是0 ,属于⼀种⽅案,也是为了后续填表是正确的。
  4. 填表顺序:
    从上往下每⼀⾏,每⼀⾏从左往右
#include <bits/stdc++.h>
using namespace std;const int N = 2010, M = 1010, MOD = 1e8;int n, m;
int a[N];
int f[N][M];int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= n; i++) cin >> a[i];f[0][0] = 1;for (int i = 1; i <= n; i++){for (int j = 0; j < m; j++){f[i][j] = (f[i-1][j] + f[i-1][((j - a[i] % m)%m +m) %m]) %MOD;        }}cout << f[n][0] - 1 << endl;return 0;
}
http://www.whsansanxincailiao.cn/news/30237096.html

相关文章:

  • 江苏建科建设监理有限公司网站/seo实战技巧
  • 昆山网站建设熊掌号/制作链接的app的软件
  • 延庆县专业网站制作网站建设/网店推广运营
  • 微网站建设申请报告/发稿
  • 怎么样建设一个电影网站/如何自己做一个网址
  • wordpress如何改页面模板/快排seo软件
  • 如何网站备案/外贸网站优化
  • wordpress伪静态 宝塔/建站seo是什么
  • 招聘网站怎么做效果好/大连百度关键词排名
  • 博尔塔拉州大型网站建设/免费cms建站系统
  • 深圳官方网站建设/网络推广怎么做?
  • 安卓软件开发工程师/站长工具seo查询
  • 网站开发难不难学/百度站长工具使用方法
  • 做旅游网站一年能挣多少/公司seo是指什么意思
  • 农业网站 源码/建站教程
  • 做网站推广托管费用/店铺推广平台有哪些
  • 关于网站建设实验报告/网络营销公司名称
  • 电子商务网站建设需要做好哪些准备/上海百度推广电话
  • 网站建设平台开发/关键词排名 收录 查询
  • 怎么做家政的网站/无锡百度竞价公司
  • 淘宝里面的网站怎么做的/关键词搜索引擎工具
  • 电脑网站建设方案/男生和女生在一起探讨人生软件
  • 腾云建站靠谱吗/天津seo推广优化
  • 做网站本溪/国家免费培训机构
  • 做网站需要视频衔接怎么/百度教育会员
  • wordpress英文字体样式/seo关键词排名技巧
  • 网站建设与维护百科/网络推广项目
  • 网站设计案例/百度平台客服电话
  • 莱州网站开发/百度手机助手app下载官网
  • 百度网站推广怎么样/短视频seo排名系统