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

Java中的动态规划THREE——DP

Java中的DP-260316

  • 多重背包问题
    • 如何实现
      • 基础版:三重循环
      • 例题(FROM 洛谷P1077 )
        • 代码实现
      • 进阶版:二进制优化时间复杂度
      • 例题(FROM 洛谷 P1776)
        • 代码实现 - 三重循环
        • 代码实现 - 二进制优化

蒽昨天状态不好休息一天,通宵通的我整个人昏昏的。
前面的两章我们讲解了01背包和完全背包问题,DP的基础模型还剩下部分背包和多重背包,我们将在本章进行讲解多重背包,部分背包问题大家自行学习一下,很简单而且偏向贪心思维。

多重背包问题

与其他问题的对比:

  • 01 背包:一个物品只有一件,选或者不选
  • 完全背包:一个物品有无数件可以取
  • 多重背包:介于上述两种问题之间,题目中限定了该物品的个数

如何实现

基础版:三重循环

在之前的背包问题上,加一层内层循环,从0~n(该物品限定数目),暴力枚举每一个物品目前的数量

例题(FROM 洛谷P1077 )

代码实现
importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scannerinput=newScanner(System.in);intn=input.nextInt();intm=input.nextInt();int[]a=newint[n];for(inti=0;i<n;i++)a[i]=input.nextInt();long[]dp=newlong[m+1];//dp[j]表示在j盆花的时候有多少方案dp[0]=1;for(inti=0;i<n;i++){for(intj=m;j>=0;j--){longvalue=0;for(intk=0;k<=a[i]&&k<=j;k++)//进行个数的枚举value=(value+dp[j-k])%1000007;dp[j]=value;}}System.out.print(dp[m]);}}

值得注意的是:计数问题(比如本题)不能二进制优化,换句话说,如果题目要求的是方案数则不能使用二进制优化,只能使用三重循环,因为二进制优化不强调路径过程,只强调结果

进阶版:二进制优化时间复杂度

上边的基础版一般来说只能通过一半的数据,一旦数字超过10^3,三重循环的复杂度将来到一个恐怖的数字,于是我们进阶出来了二进制优化的版本。该版本的原理是:将一件物品的限制数目看作一个整体,用二的倍数将其分割为n块,再用01背包问题,遍历该分割后的物品选 or 不选。分割的时候要注意,如果余数已经不足2^n,要将余数直接单独分割成一个物体。比如:一个物品有13个,根据二进制优化,我们将其分为1、2、4、6(余数)。

例题(FROM 洛谷 P1776)


本题将给出两种解法,基础版和进阶版,基础版可以作为三重循环的巩固,但是在题目里只能得到50分,进阶版可以拿满分,但是需要一些理解。

代码实现 - 三重循环
importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scannerinput=newScanner(System.in);intn=input.nextInt();intW=input.nextInt();int[]v=newint[n];int[]w=newint[n];int[]m=newint[n];for(inti=0;i<n;i++){v[i]=input.nextInt();w[i]=input.nextInt();m[i]=input.nextInt();}long[]dp=newlong[W+1];dp[0]=0;//dp[j]表示在j重量的时候最大价值for(inti=0;i<n;i++){for(intj=W;j>=0;j--){for(intk=0;k<=m[i]&&k*w[i]<=j;k++){dp[j]=Math.max(dp[j],dp[j-k*w[i]]+k*v[i]);}}}System.out.print(dp[W]);}}
代码实现 - 二进制优化
importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scannerinput=newScanner(System.in);intn=input.nextInt();intW=input.nextInt();List<Integer>v=newArrayList<>();//动态数组接收分割后的物品价值List<Integer>w=newArrayList<>();//动态数组接收分割后的物品质量for(inti=0;i<n;i++){intvv=input.nextInt();//价值intww=input.nextInt();//质量intmm=input.nextInt();//物品数目限制intk=1;//二进制初始化while(k<=mm){//如果还能分就接着分v.add(vv*k);//将单个价值(vv)与分割大小(k)相乘,得到分割后“本块”的价值w.add(ww*k);//与价值同理,得到质量mm-=k;//每分一块,将总数量减去分割走的数量k*=2;//二进制,1、2、4、8、16…………每次乘2}if(mm>0){//如果不够分了,但是还有余数,把余数单独作为一块v.add(mm*vv);w.add(mm*ww);}}long[]dp=newlong[W+1];//dp[j] 代表在j重量的时候的最大价值for(inti=0;i<w.size();i++){//01背包问题代码intweight=w.get(i);intvalue=v.get(i);for(intj=W;j>=weight;j--){dp[j]=Math.max(dp[j],dp[j-weight]+value);}}System.out.print(dp[W]);}}
http://www.cnnetsun.cn/news/1333489.html

相关文章:

  • 20260317_163145_SRC挖掘?看这篇就够了,保姆级教程带你飞!
  • 重新标注ImageNet!128万张图像,单标签变多标签!这个预训练模型让COCO暴涨4个点
  • skynet Monitor 线程详解
  • 2026笔记本Windows电源管理:硬盘休眠与PCIe链路
  • Python 实战:基于朴素贝叶斯的中文评价情感分析(好评 / 差评自动识别)| 附完整可运行代码
  • 一文详解Diffusion Policy
  • C++11中智能指针:shared_ptr的引用计数是线程安全的吗?
  • 不懂代码,我用AI编程给5岁女儿开发了个流光画板(带你一步一步设计一个属于自己的流光画板)
  • VScode快捷键
  • 小白从零开始勇闯人工智能:LangChain 入门指南(下)
  • AI时代的教育“外包”:中国家长将作业辅导交给机器
  • 2026年课程论文降AI率工具推荐:便宜好用才是硬道理
  • 软件系统安全赛初赛misc题-steganography wp
  • 东方仙盟・神识共创共生,智启万象—架构思路—未来之窗行业应用跨平台架构
  • linux-安装配置jdk mysql redis elasticsearch
  • Python 之程序截图的几种方式(含chromedriver下载链接)
  • android studio项目 gradle-xx-bin.zip下载失败或很慢的解决方法
  • AperiSolve 开源项目教程
  • 企业决策视角下微服务全链路性能瓶颈分析平台对比及实践指南
  • 【C语言】程序环境与预处理
  • SCUT_thesis项目:解决长章名换行后不居中的排版问题
  • PowerPlatformConnectors三大类型深度对比:自定义、认证与独立发布者连接器怎么选?
  • Pleaserun vs 手动编写init脚本:效率提升10倍的秘密
  • dbblog部署教程:Docker容器化部署与服务器配置全流程
  • AniVu BitTorrent下载功能深度测评:速度与稳定性全面测试
  • DC-TTS语音合成效果对比:LJ Speech与KSS数据集实测
  • 提升Haskell开发效率:ghcid高级功能与实用技巧
  • Saasify:让API变现从未如此简单!一站式实现API商业化的终极指南
  • Ikemen-GO开发者指南:用Go语言构建自定义格斗游戏引擎
  • GoMLX未来路线图:即将发布的5大令人期待的功能