递增

题目描述
现有数列A_1,A_2,\cdots,A_NA1​,A2​,⋯,AN​,修改最少的数字,使得数列严格单调递增。

输入格式
第1 行,1 个整数N

第2 行,N 个整数A_1,A_2,\cdots,A_NA1​,A2​,⋯,AN​

输出格式
1 个整数,表示最少修改的数字

输入输出样例
输入 #1复制
3
1 3 2
输出 #1复制
1
说明/提示
• 对于50% 的数据,N \le 10^3N≤103

• 对于100% 的数据,1 \le N \le 10^5 , 1 \le A_i \le 10^91≤N≤105,1≤Ai​≤109

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
    int n,ans=1;
    scanf("%d",&n);
    int a[n],sa[n];
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    sa[ans]=a[0];
    for(int tz,i=1;i<n;i++){
        if(sa[ans]<a[i]){
            ans++;
            sa[ans]=a[i];       
        }else{
            tz=lower_bound(sa,sa+ans,a[i])-sa;
            sa[tz]=a[i];
        }
    }
    printf("%d",n-ans);
    return 0;
}
### 数位递增的概念 数位递增是指一个正整数中的每一位数字都不大于其右侧相邻的数字。换句话说,对于任意位置 \(i\) 的数字 \(d_i\) 和其右侧相邻的位置 \(j\) 的数字 \(d_j\) (其中 \(i < j\)),满足条件 \(d_i \leq d_j\)。例如,1135 是一个数位递增的数,因为它的每一位都小于等于下一位;而 1024 不是数位递增的数,因为在第二位上出现了较大的数字。 这种定义可以通过逐位比较来验证一个数是否属于数位递增类别[^3]。 --- ### 实现方法与算法 #### 方法一:字符串处理方式 通过将数字转换为字符串形式逐一比较字符大小,可以判断该数是否为数位递增的数。以下是 Python 中的一种实现: ```python def count_increasing_numbers(n): ans = 0 for number in range(1, n + 1): # 遍历从 1 到 n 的所有数字 s = str(number) # 将当前数字转为字符串 flag = True # 假设当前数字符合条件 for j in range(1, len(s)): if s[j - 1] > s[j]: # 如果前一位大于后一位,则不符合条件 flag = False break # 提前退出循环 if flag: # 若标志仍为真,则计数加一 ans += 1 return ans # 返回最终的结果 if __name__ == "__main__": n = int(input()) result = count_increasing_numbers(n) print(result) ``` 这种方法的时间复杂度主要取决于输入范围内的遍历次数以及每次内部的逐位对比操作,总体时间复杂度大约为 O(k * log₁₀n),其中 k 表示总共有多少个数需要被检测,log₁₀n 表示平均每个数所含有的位数。 --- #### 方法二:动态规划优化 另一种更高效的解决方案涉及动态规划的思想。我们可以预先计算出不同长度下的可能组合数目,并利用这些预计算结果快速得出答案。具体来说,假设 dp[l][k] 表示长度为 l 并且最高位不超过 k 的有效数位递增数量,则状态转移方程如下所示: \[ dp[l][k] = \sum_{m=0}^{k}{dp[l-1][m]} \] 初始条件设置为当长度为 1 时,任何单个数字都是有效的数位递增数。因此有: \[ dp[1][k] = k+1,\quad 对于所有的 k \in [0..9] \] 最后统计范围内所有合法数值即可得到总数目。此方法能够显著减少重复运算量,在大规模数据集上的表现优于简单枚举法[^1]。 --- #### Java 实现最长连续递增子序列 虽然题目询问的是关于数位递增的具体概念及其应用,但这里也提供一段基于数组寻找最长严格单调上升子串的代码作为补充说明,这有助于理解如何高效地判定一系列元素之间的相对顺序关系: ```java class Solution { public int findLengthOfLCIS(int[] nums) { if (nums.length == 0) return 0; int max = 0; int num = 1; for (int i = 0; i < nums.length - 1; i++) { if (nums[i] < nums[i + 1]) { num++; } else { if (max < num) max = num; num = 1; } } return Math.max(num, max); } } ``` 上述代码片段展示了如何在一个整型数组中找到最长连续递增子序列的长度。尽管它并不直接解决原问题,但它体现了类似的逻辑思维过程——即通过对前后项之间差值或者大小关系进行评估从而完成特定目标的任务[^2]。 --- ### 总结 综上所述,无论是采用简单的暴力枚举还是复杂的动态规划策略都可以有效地解决问题。选择哪种技术路线应视具体情况而定,比如性能需求、开发周期等因素都会影响决策方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值