最大产品切割算法

如何解决最大产品切割算法

我正在查看发布在https://www.geeksforgeeks.org/maximum-product-cutting-dp-36/#:~:text=Given%20a%20rope%20of%20length,is%20more%20than%202%20meters上的问题。

问题陈述是

给出一根长度为n米的绳索,以使所有部分的长度乘积最大化的方式将绳索切成整数长度的不同部分。您必须至少裁切一次。假设绳子的长度超过2米。

可以通过动态编程轻松解决。这是他们的解决方案

...

<!-- Bitcoin part -->

<div style="height: 500px">
    <!-- just to make scrolling effect possible -->
    <h2 class="myH2" style="padding-bottom: 50px;">Bitcoin</h2>
    <div  class="text-center" id="myData" style="margin-left:500px; font-weight: bold; color: indianred;"></div>
    </div>
<!-- Bitcoin part ends -->





...

<!-- Function used to display json file -->
<script>
    fetch("currentprice.json")
        .then((response) => response.json())
        .then(appendData)
        .catch(console.error);

    function appendData(data) {
        const dataFragment = document.createDocumentFragment();
        for (const price of Object.values(data.bpi)) {
            dataFragment.appendChild(createPriceElement(price));
        }
        document.getElementById("myData").appendChild(dataFragment);
    }

    function createPriceElement(price) {
        const div = document.createElement("div");
        div.innerHTML = `<table><tr><th>Code&nbsp&nbsp&nbsp&nbsp&nbsp</th><th>Symbol&nbsp&nbsp&nbsp&nbsp&nbsp</th><th>Rate</th><th>Description&nbsp&nbsp&nbsp&nbsp&nbsp</th><th>Rate float</th></tr><tr>
            <td> ${price.code} &nbsp&nbsp&nbsp&nbsp&nbsp <td>   ${price.symbol}&nbsp&nbsp&nbsp&nbsp&nbsp<td>  ${price.rate}&nbsp&nbsp&nbsp&nbsp&nbsp</td><td>  ${price.description} </td><td> ${price.rate_float}</td>
        </tr></table> <br><br>` ;

        return div;
    }


    setInterval(function(){
        reload() // this will run after every 5 seconds
    },5000);
</script>
<footer style="text-align: center; padding: 3px;background-color: crimson;  color: white;">
E...
</footer>
</body>
</html>

我的问题是,为什么内循环仅转到// A Dynamic Programming solution for Max Product Problem int maxProd(int n) { int val[n+1]; val[0] = val[1] = 0; // Build the table val[] in bottom up manner and return // the last entry from the table for (int i = 1; i <= n; i++) { int max_val = 0; for (int j = 1; j <= i/2; j++) max_val = max(max_val,(i-j)*j,j*val[i-j]); val[i] = max_val; } return val[n]; } 而不是i/2是有效的?这似乎是利用对称性。但是max函数也超过了i - 1,似乎我们对j * val[i - j]感到厌恶。

解决方法

让我们在这里暂时退出DP解决方案,因为我认为这是基于解决方案的数学特性。

让我们想象一下,您必须将k条切成长度为n的绳索。这比您所说的问题要严格得多,在问题中您可以进行任意(正数)切割。理想的解决方案是什么样的?如果可以随意切割,而不仅仅是整数切割,最好的答案是将绳索切成k块大小为n / k的碎片。为什么是这样?好吧,假设您不这样做。这意味着有些片段必须大于平均值(例如,其大小至少为n / k +ε),而某些片段必须小于平均值(例如,其大小最多为n / k-ε)。那么这两块的乘积最多为

(n / k +ε)(n / k-ε)

=(n / k) 2 2

请注意,ε越大,即散件尺寸之间的差异越大,则乘积越小。这意味着最好改变这些切割方式,使它们的尺寸更接近平均n / k。

即使切割必须为整数大小,也适用相同的逻辑。例如,想象一下,两块的大小至少相差两个。写下一块的大小至少为m + d,另一块的最大大小为m-d。那么这些块的乘积为m 2 -d 2 ,因此最好使它们尽可能接近其平均值,以使d小。

那么为什么n / 2的上限呢?好吧,上述推论表明,如果要进行k割,我们应该将值保持尽可能的接近,尤其是对于k割,任何块的尺寸都不应大于⌈n/k⌉。在k = 2的情况下,最大片段不得大于⌈k/2⌉。我认为这就是界限的来源。

实际上,我很确定此论点意味着可以更快地解决此问题。与其在每个点上切掉任意数量并谈论进行任意数量的切割,不如对切割的数量进行迭代。对于每一个裁切,我们都知道裁切的尺寸是多少-使裁切的尺寸尽可能接近平均尺寸。无需使用任何DP来执行此操作。用伪代码:

max_cut = 0
for cuts = 2 to n:
    average_rounded_down = n // cuts
    pieces_above_average = n % cuts
    pieces_below_average = cuts - pieces_below_average
    value_of_this_cut = (average_rounded_down) ** pieces_below_average + (average_rounded_down + 1) ** pieces_above_average
    if max_cut < value_of_this_cut:
         max_cut = value_of_this_cut

这在时间O(n)上运行,而忽略了将值提升为不同幂的代价(公平地说,不是O(1))。

我相当确定可以通过使用二进制搜索之类的东西来改进对最佳切割数的搜索,从而进一步改善这一点,但是可惜我现在没有时间来研究如何做到这一点。 。 :-)

,

problem source给出的算法的解释:

我们可以看到有很多子问题可以再次解决, 再次。由于再次调用了相同的子问题,因此出现了此问题 重叠子问题属性。 典型的动态规划(DP)问题,相同的计算结果 通过构造一个临时数组val []可以避免子问题 自下而上的方式。

尽管这从技术上讲可以解释推理,但该解释并不能说明所有内容。原始作者没有很好地解释他们对实际代码的思考过程。因此,任何人所能做的最好的就是猜测他们在想什么。如果仅查看i<=5案例,则可能会争辩说作者看到了这种对称性并将其切断。他们以n=5案例为例,证明了这一论点。

为进一步说明,下图显示了循环迭代时max函数的输出。黄色表示使用j <= i/2而不是j <= i可以跳过的迭代。 j=0行表示循环开始之前的val数组,'-'值表示未初始化的值。

enter image description here

这些结果还将显示它们如何进一步简化程序。结果表明,每大于i的{​​{1}},最大值始终位于4行中。

如果我们看到一些有关此问题的示例,则可以轻松观察到 以下模式。可以反复获得最大积 在尺寸大于4时切割尺寸为3的零件,并保持最后 部分,大小为2或3或4。例如,n = 10,即最大乘积 由3、3、4获得。对于n = 11,最大乘积由 3、3、3、2。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-