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

动态规划:砝码称重(01背包-闫氏DP分析法)

动态规划:砝码称重(01背包-闫氏DP分析法)

砝码称重

www.acwing.com/problem/content/3420/

在这里插入图片描述

DP:

  • 状态表示:f[i][j]

    • 集合:只用前 i i i 个砝码,测出重量为 j j j 的所有方案
    • 属性:bool
  • 状态计算: f [ i ] [ j ] = f [ i − 1 ] [ j ] ∣ ∣ f [ i − 1 ] [ j − w [ i ] ] f[i][j]=f[i-1][j]\ \ ||\ \ f[i-1][j-w[i]] f[i][j]=f[i1][j]  ∣∣  f[i1][jw[i]]

对于本题,由于砝码可以放在天平两侧,可以将一个砝码拆为一正一负,用来表示放在天平的哪一侧,最后统计大于 0 的部分即可

实现方式有两种:

  1. 分开 DP,需要改变遍历顺序(仅一维的情况,二维不需要考虑),因为当 w[i]​ 为负数时,要获取上一层的数据应该从小到大(和 w[i]​ 为正数时相反)
  2. 构造一个大数组,设定一个基准 B B B 作为零度线,这样就将负数和正数的组成方案全部放在同一个数组中,最后只要统计大于 B B B 的结果即可
import java.util.*;public class Main {static final int N = 200010;static int[] w = new int[N];static boolean[] f = new boolean[N];public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int sum = 0;for (int i = 1; i <= n; i++) {w[i] = sc.nextInt();w[i + n] = -w[i];sum += w[i];}// dp砝码全放一侧f[0] = true;for (int i = 1; i <= n; i++) {for (int j = sum; j >= 0; j--) {if (j - w[i] >= 0) {f[j] = f[j] || f[j - w[i]];}}}// dp砝码放两侧,遍历顺序不同for (int i = n + 1; i <= 2 * n; i++) {for (int j = 0; j <= sum; j++) {// 此时w[i]均为负数f[j] = f[j] || f[j - w[i]];}}int count = 0;for (int i = 1; i <= sum; i++) {if (f[i]) {count++;}}System.out.println(count);}
}

相关文章:

  • SVN本地使用--管理个人仓库
  • CSS语法中的选择器与属性详解
  • vs code配置go开发环境以及问题解决 could not import cannot find package in GOROOT or GOPATH
  • Linux》》Shell脚本 基本语法
  • Apptrace如何帮我精准追踪移动广告效果?
  • Kernel K-means:让K-means在非线性空间“大显身手”
  • Java数据结构——第 2 章线性表学习笔记
  • 哈夫曼树Python实现
  • 目标检测之YOLOV11谈谈OBB
  • maven项目无远程仓库开发配置(无外网、无maven私服)
  • “本地化思维+模块化体验”:一款轻量数据中心监控系统的真实测评
  • angular 图斑点击,列表选中并滚动到中间位置
  • 【目标检测】IOU的概念与Python实例解析
  • SQL分片工具类
  • Stable Diffusion 实战-手机壁纸制作 第二篇:优化那些“崩脸”和“马赛克”问题,让图像更加完美!
  • Softhub软件下载站实战开发(五):分类模块实现
  • C语言学习day17-----位运算
  • LeeCode94二叉树的中序遍历
  • SpringBoot定时监控数据库状态
  • thinkphp8 模型-一对一,一对多,多对多 学习
  • 静态网站开发实训报告/整合营销是什么
  • 广州大型网站建设公司/域名免费查询
  • 安远县建设局网站/编程培训班学费一般多少钱
  • 青岛网站制作/关键词优化话术
  • 兰州网站设计/宁波优化关键词首页排名
  • 专注苏州网站优化/阿里指数官网