学到的新东西<map>离散化以及关于状态的思考;这里有一个初状态以及末状态;

失衡天平

https://ac.nowcoder.com/acm/problem/19158

在背包问题中,当我们使用map(或unordered_map)来存储动态规划的状态时,我们实际上是在实现一种离散化的过程。离散化是一种数据预处理技术,用于将大范围的数值映射到较小的、连续的范围内,以便更有效地存储和计算。

在背包问题中,背包的容量通常是一个较大的整数范围,但如果不是所有的容量都会被实际使用到(即,不是所有的物品组合都会导致每个可能的容量被访问),那么使用数组来存储DP状态将会非常浪费空间。而map(或unordered_map)则提供了一种按需分配空间的方式。

具体来说,当我们尝试更新一个背包容量为j的状态时,我们首先检查dp[j]是否已经被创建。如果j还没有被访问过,那么dp[j]在map中就不存在,此时我们可以安全地创建一个新的键值对来存储这个状态。如果j已经被访问过,那么dp[j]已经在map中存在,我们可以直接更新它的值。

这种方式的好处是,我们只为实际使用到的背包容量分配了空间,从而大大减少了内存的使用。同时,由于map内部使用了红黑树(对于map)或哈希表(对于unordered_map)来存储键值对,查找和更新操作的时间复杂度都是对数级别或接近常数级别的,因此效率也是可以接受的。

总结来说,使用map(或unordered_map)来实现背包问题的DP状态存储,不仅实现了离散化,减少了空间的使用,而且保持了较高的时间效率。

在动态规划问题中,我们通常要定义状态来表示某个阶段或某个子问题的解。在这个特定的问题中,状态 dp[i][j] 表示考虑前 i 个物品时,天平两端的质量差为 j 的情况下,较重一端能够达到的最大质量。

当我们考虑第 i 个物品时,我们有三种选择:

不放第 i 个物品:这种情况下,天平两端的质量差仍然为 j,我们继承前一个状态 dp[i-1][j] 的结果。
将第 i 个物品放在天平的左边:如果我们选择将第 i 个物品放在天平的左边,那么天平两端的质量差将会增加 a[i](因为左边增加了质量)。因此,在只考虑前 i-1 个物品时,质量差应该为 j - a[i],以便加上第 i 个物品后达到质量差 j。所以我们查看 dp[i-1][j-a[i]] 的值,并加上当前物品的质量 a[i]。
将第 i 个物品放在天平的右边:如果我们选择将第 i 个物品放在天平的右边,那么天平两端的质量差将会减少 a[i](因为右边增加了质量,但我们是用“左减右”来定义质量差的,所以实际上是减少了)。因此,在只考虑前 i-1 个物品时,质量差应该为 j + a[i],以便加上第 i 个物品后达到质量差 j。但这里需要注意的是,我们实际上只关心左边(较重的一端)的总质量,所以我们直接查看 dp[i-1][j+a[i]] 的值(它表示在质量差为 j+a[i] 时左边能达到的最大质量)。
所以,j-a[i] 和 j+a[i] 分别是我们在考虑第 i 个物品之前的两种可能的质量差,它们分别对应着将第 i 个物品放在天平左边和右边的情况。
//一道极其有意思的变相的问题
#include<bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const int N = 105 * 100 + 5;
int dp[105][2 * N], a[105];
int main() {
  int n, m;
  cin >> n >> m;
  for(int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  memset(dp, -0x3f, sizeof(dp));
  dp[0][0] = 0;
  for(int i = 1; i <= n; i++) {
    for(int j = 0; j <= N-100; j++) {
      dp[i][j] = dp[i - 1][j];
      dp[i][j] = max(dp[i][j], dp[i - 1][abs(j - a[i])] + a[i]);
      dp[i][j] = max(dp[i][j], dp[i - 1][j + a[i]] + a[i]);
    }
  }
  int ans = -1;
  for(int i = 0; i <= m; i++) ans = max(ans, dp[n][i]); 
  cout << ans << "\n";
  return 0;
}
```考虑三个子状态的过程完全就是nice,nice
全部评论

相关推荐

2024-12-04 22:59
已编辑
江苏科技大学 后端
0offer要鼠啦:为啥没写会玩青钢影
点赞 评论 收藏
分享
2024-12-09 16:42
门头沟学院 Java
程序员牛肉:我愿称你这种简历为npc简历。特点就是毫无任何亮点。你简历没有任何问题,但就是太普通了。实在是太普通了。 你可以在牛客搜一搜有多少人的简历和你一摸一样。一个大一点的公司一天能收几百份简历,你要是有公司邮箱的话,你可以尝试一下。在这几百份简历中,面试官面试一个人就需要1个小时。一天最多面试5个人。 照这样算,一个部门抽出3个人来面试,一天面试15个人。10天也最多面试150个人。在如此悬殊的投递和面试比之下,面试官一天要翻大量的简历。你这种简历真的是毫无亮点,面试官真的很难激起面试你的欲望。 没有学历,没有好的项目,技术也一般。写简历真的是给人乱写的感觉。 第一个项目中,使用mybatis plus这个插件来和数据库进行交互也可以作为亮点吗?基于nacos实现一个微服务中的服务注册也算亮点?第二个项目还是黑马点评。像有这种项目的简历一抓一大把。 问题来了:你觉得面试官为什么会面试你?在简历大致相同的情况下,你学校又是个二本,你认为面试官选择你而不选择学历更高的同学的原因是什么? 所以我觉得对于你来讲,可以一边投递实习,一边准备新的项目。同时积极去探索一些自己能够写到简历上的亮点。比如是不是有自己的公众号或者博客。比如是不是有自己开源项目,比如是不是一些含金量比较高的比赛 想要有面试机会的第一步就是让自己从这种npc简历中跳出来,最起码有一点“活人”的气息
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务