第一行输入一个正整数,代表数组的元素数量。
第二行输入个正整数
,代表数组的元素。
一个整数,代表最小的操作次数。
3 3 2 4
2
一种合法的操作如下:
第一次选择区间[2,2],数组变成[3,3,4]。第二次选择区间[2,3],数组变成[3,4,5],满足要求。请注意,这里的区间指选了第几个数。例如区间[2,2]代表选了第二个数,区间[2,3]代表选了第二个和第三个数。
#include <iostream>
using namespace std;
/**
* 首先第一个点肯定不提升
* 1、考虑第二个点怎么提升:假设对于第二个点的一个提升区间是[2,k],那不如直接提升
* 区间[2,n]。因为反正要把k+1往后的都提升得比k高,既然k都提升了,则把后
* 面的一同提升也没有坏处,证明是:
* (假设最优提升策略的某个提升区间是[2,k],我们把该区间改为[2,n],其它
* 提升区间不变,则结果数组的[k+1,n]部分都升高了同一个值,仍然是严格递
* 增的,因此也是一个最优提升策略)。
* 类似地,往后每个点开始的提升区间,都不妨直接延伸到n。
* 所以可以认为任何一个提升区间都是[t,n]的形式,并且多个相同的[t,n]可以合并为一个。
*
* 2、提升[t,n],对于区间[t,n]的点的相对高度没有影响,
* 因此区间[t+1,n]要提升的高度,
* 1)如果arr[t+1]<=arr[t]的话,其实就是arr[t+1]-arr[t]+1。
* 2)否则就不用专门提升该区间。
*/
int main() {
int n;
long count = 0;
cin>>n;
long prev,tmp;
cin>>prev;
for(int i=1;i<n;i++){
cin>>tmp;
if(prev>=tmp)
count+=prev-tmp+1;
prev=tmp;
}
cout<<count;
}
// 64 位输出请用 printf("%lld") package main
import "fmt"
var total = 0 //总操作数
func main() {
var num int
fmt.Scan(&num)
a := make([]int, num)
for i := 0; i < num; i++ {
fmt.Scan(&a[i])
}
// 倒置
for i := 0; i < num/2; i++ {
a[i], a[num-i-1] = a[num-i-1], a[i]
}
fmt.Println(a)
for i := 1; i < num; i++ {
if a[i] >= a[i-1] { // 新加入的a[i]不会受到a[i-1]的影响,下次计算保持原值,就很方便
total += a[i] - a[i-1] + 1
}
}
fmt.Println(total)
}
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> v(n, 0);
for (auto&e: v) cin >> e;
int i = 0;
int64_t ret = 0;
while (i < v.size()-1) {
if (v[i] >= v[i+1])
ret += v[i] - v[i+1] + 1;
i++;
}
std::cout<<ret<<std::endl;
}
// 64 位输出请用 printf("%lld")
# 贪心:区间严格递增的最少操作次数 # 4 2 9 19 2 -->将后面的数都递增:4 5 12 22 5 等价于只递增一个数:4 5 9 19 2 # 因为他们的差值不变 # 只需要找到第一个开始减小的位置,然后计算差值 n = int(input()) line1 = input() num = list(map(int, line1.split())) count = 0 dif = 0 for i in range(1,len(num)): if num[i] <= num[i-1]: dif = num[i-1] - num[i] + 1 count += dif print(count)