高階指南IncDec Sequence

2021-10-08 10:36:15 字數 1268 閱讀 6201

一道典型的差分+貪心

首先我們來了解一下差分的原理

差分是字首和的逆運算,差分陣列往往是這樣定義的:

b[i]=b[i]-b[i-1]

b[1]=a[1];

根據這個定義我們可以看出,如果b[i]=b[i-1]那麼差分序列的值就會是0.有因為b[1]=a[1].所以如果從2到末尾的差分序列的值都為0,那麼序列中的所有數就都一樣了。

題目中的把所有數都變成一樣就變為了,把從0到末尾的差分序列全部變成0.

既然如此,我們如何求得最少的操作次數呢?

我們可以以0為分界線,把整個差分序列分成正負兩種情況(因為值為0的差分序列表示前後的數一樣,不需要我們操作了).

又因為我們每次只能對區間±1,所以為了把整個序列都變成0。我們只需要把所有正數都變成0,再把所有負數都變成0.

其實把正數-1和把負數+1這兩個操作是可以同時進行的。

如果我們要對乙個區間進行修改而不改變區間以外的數,則可在差分序列中進行如下操作。(對於區間[l,r])

b[l]+=1; b[r+1]-=1;

由這個式子可以知道我們可以知道兩個修改時可以同時進行的。但假如差分序列中正數的個數和負數的個數不一樣,我們就要選擇讓這個數(多出來的正數或負數)和b[1]或b[n+1]進行配對

所以最少運算元=min(差分序列中的正數之和,差分序列中的負數之和)

最終序列可能的情況:

1.如果正數之和=負數之和的話,那麼整個序列就只有一種情況。

2.整數之和!=負數之和的話,序列情況=單個和b[1],b[n+1]操作的個數+1(正數和負數相等的時候)

//注意變數要定義成ll

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

ll n;

const

int max=

100100

;int a[max]

;int

main()

cout<<

max(bigger,smaller)

<

cout<<

abs(bigger-smaller)+1

<

return0;

}

ACM高階指南

acm隊不是為了一場比賽而存在的,為的是隊員的整體提高。大學期間,acm隊隊員必須要學好的課程有 l c c 兩種語言 l 高等數學 l 線性代數 l 資料結構 l 離散數學 l 資料庫原理 l 作業系統原理 l 計算機組成原理 l 人工智慧 l 編譯原理 l 演算法設計與分析 除此之外,我希望你們...

Acm高階指南

acm隊不是為了一場比賽而存在的,為的是隊員的整體提高。大學期間,acm隊隊員必須要學好的課程有 l c c 兩種語言 l 高等數學 l 線性代數 l 資料結構 l 離散數學 l 資料庫原理 l 作業系統原理 l 計算機組成原理 l 人工智慧 l 編譯原理 l 演算法設計與分析 除此之外,我希望你們...

ACM高階指南

acm隊不是為了一場比賽而存在的,為的是隊員的整體提高。大學期間,acm隊隊員必須要學好的課程有 l c c 兩種語言 l 高等數學 l 線性代數 l 資料結構 l 離散數學 l 資料庫原理 l 作業系統原理 l 計算機組成原理 l 人工智慧 l 編譯原理 l 演算法設計與分析 除此之外,我希望你們...