CF189A Cut Ribbon(dp一维思想,完全背包最详细解析)

简介: CF189A Cut Ribbon(dp一维思想,完全背包最详细解析)

题目描述



Polycarpus has a ribbon, its length is nn . He wants to cut the ribbon in a way that fulfils the following two conditions:


  • After the cutting each ribbon piece should have length aa , bb or cc .
  • After the cutting the number of ribbon pieces should be maximum.


Help Polycarpus and find the number of ribbon pieces after the required cutting.


输入格式



The first line contains four space-separated integers nn , aa , bb and cc (1<=n,a,b,c<=4000)(1<=n,a,b,c<=4000) — the length of the original ribbon and the acceptable lengths of the ribbon pieces after the cutting, correspondingly. The numbers aa , bb and cc can coincide.


输出格式



Print a single number — the maximum possible number of ribbon pieces. It is guaranteed that at least one correct ribbon cutting exists.


题意翻译



给一长度为n的缎带,要求将其剪成若干长度为a,b,c的缎带,且缎带数量尽可能多。

输入格式: 输入仅一行,四个正整数n,a,b,c(n,a,b,c≤4000)。

输出格式: 输出仅一行,即缎带数量的最大值。


输入输出样例



输入 #1复制

5 5 3 2


输出 #1复制

2


输入 #2复制

7 5 5 2


输出 #2复制

2


dp解析,

#include<bits/stdc++.h>
using namespace std;
int n,a[12],f[120000];
int main() {
    cin>>n>>a[1]>>a[2]>>a[3];
    memset(f,-1,sizeof f);//为啥是-1,其他不行吗? 
    f[0]=0;//为啥一定要是f[0],我f[1]不行吗?
    for(int i=1;i<=3;i++)
        for(int j=a[i];j<=n;j++){
            if(f[j-a[i]]<0) continue;//当 j=a[i]为0我们就不用退出,或者踩到前面我们定义的f[j],我等下会解释为啥这样会可以统计出正确值。
            f[j]=max(f[j],f[j-a[i]]+1);//更新最大值,等下我也会解释,
        }
    cout<<f[n];//戚,为啥输出f[n],我输f[n-1]其他的不行吗?
    return 0;
}


1、首先我们考虑memset这个函数是初始0和-1;其他的必错;

2,为啥我们f[0]=0;而不是f[1]=0;因为我们执行下面循环的判断,代表着我们刚刚开始循环的时候可以切下我们指定的彩带,也就是存下来。


3.例如          如果是 5 5 3 2

第一轮是a[1]=5 然后f[5]=1;

    第二轮的时候a[2]=3 会给f[3]赋值1;

            第三轮   a[3]=2 ,f[2]=1;这时候我们继续j++,发现循环到j=5,我们f[j-2]=f[3]=1;这个我们发现了  if(f[5-a[3]]<0) continue;不符合,所以我们可以执行下面的循环  f[j]=max(f[j],f[j-a[i]]+1);最后就是f[5]=2;为什么会这样呢,因为我们看成我们剪了一个长度为2的彩带,然后我们继续j++的时候发现当j=5,我们f【3】=1,可以继续执行循环相当于又可以剪一刀,这个时候我们由统计了一个f【5】的值,然后我们通过循环max取出最后的值f【n】就是我们要的答案。


4.最后为啥是f[n],因为我们的背包是n,所以我们取f[n]。


最后,为什么这样减是最多的,因为我们用了 f[j]=max(f[j],f[j-a[i]]+1);//更新f[j]最大值,,这里我们最后输出的f【n】,代表背包体积是n;


相关文章
|
负载均衡 Java API
Feign 进行rpc 调用时使用ribbon负载均衡源码解析
Feign 进行rpc 调用时使用ribbon负载均衡源码解析
169 11
|
负载均衡 Java 索引
Spring Cloud 五大核心组件解析之Ribbon组件IRule详解(上)
Spring Cloud 五大核心组件解析之Ribbon组件IRule详解(上)
|
负载均衡 算法 Java
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
358 0
|
Java 调度 Spring
Spring Cloud 五大核心组件解析之Ribbon组件IRule详解(下)
Spring Cloud 五大核心组件解析之Ribbon组件IRule详解(下)
|
负载均衡 算法 网络协议
Spring Cloud 五大核心组件解析之Ribbon简介
Spring Cloud 五大核心组件解析之Ribbon简介
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
342 2
|
8月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
817 29
|
8月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
322 4
|
8月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
8月前
|
移动开发 前端开发 JavaScript
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。

推荐镜像

更多
  • DNS