洛谷P1021 [NOIP1999 提高组] 邮票面值设计(题解)

博主解析了一道关于连续数生成的编程题,涉及动态规划策略。通过理解数列范围和构建dp数组来确定最大连续数。关键步骤包括确定每个数的范围、暴力搜索和使用dp求解最大连续子序列。分享了解题思路和核心代码实现。

链接:
https://www.luogu.com.cn/problem/P1021

现在的状态就是找到一个提高题来做,做了半天,被迫看题解。一道题从读题,想思路,看题解,真正明白,写代码。前前后后差不多两三个小时就过去了(果然蒟蒻的本质始终没变~ - ~)

就来看这个题吧:

题意:

给你两个数n和k,k代表自定义k个不同的数,n代表从k中取n个数(可重复),最后由这n个数可以组成连续的从1到max的数,输出max的最大值和最大值对应的K和不同的数的值。

思路:

因为只是看懂了别人的思路就开始写这篇博客了,主要的是怕在写代码的时候万一由出现代码不过关,调试几个小时的情况导致没心情写思路。

思路是这样的,我们首先要知道,如果要完成从1开始到某个数连续的话,这k个数是有一定的范围的。

就拿n=3,k=3为例来说吧
首先k的第一个数肯定是1(不用质疑)
k的第二个数,他的最小是就是2,他的最大值的话,因为n=3,全部由1来构成的话最多是3。所以第二个数最大是4。
以此类推:f[1]=1; f[i]=(f[i-1]+1,f[i-1] * n+1);
我们知道了每一个数的范围就可以用暴力搜索的方法。

在这里插入图片描述

像是这样,在n=3,k=3的条件下,从1,2,3开始搜索,直到搜索到1,4,7.从中找出能够使连续达到最大的那一组数输出。

对每一组符合条件的数来进行查找看看他们能够遍历的最大数是多少。

现在就剩下一个问题了,就是怎么找到每组数中能够达到的最大连续数了。

这个大问题最后就简化成一个给定一组固定的数让你求他能够组成的最大连续数的问题了。一看最大最小,就应该会想到dp了。那么怎么求呢?
因为是连续的我们可以从1开始,然后看这组数能不能在n个数之内组成。
那么dp数组代表的意思就是:dp[i]代表第i个数能用给定的数中最少几个数来表示。
dp方程:dp[i]=min(dp[i],dp[i-f[j]]+1);

这一部分的代码就是

while(dp[i]<=n)
            {
   
   
                i++;dp[i]=INF;
                for(int j=1;j<=k&&i-f[j]>=0;j++)
                {
   
   dp[i]=min(dp[i],dp[i-f[j]]+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨晓翔同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值