IncDec序列(差分 貪心)

2021-09-25 23:27:45 字數 1161 閱讀 5201

原題鏈結

題目大意

給定乙個序列,可以在其連續子串行上進行加一或者減一操作,求使整個序列變成相同數的最小運算元和種數。

思路首要要明確是對[l,r]序列進行加一或者減一操作,可以聯想到字首和,我們對乙個陣列b的第l項進行減一操作,第r+1項進行加一操作,這樣作用到b陣列的字首和序列就是連續的區間段[l,r]內全部進行減一操作。

這樣可以把o(m*n)的時間複雜度轉化為o(n)。

這時候就要利用到差分,之前我也不是很懂,雖然它很簡單昨天睡覺前又看了一遍才徹底搞明白。

差分:對於序列a為:a1,a2,a3,……,an;

a的差分序列b:b1,b2,b3,……,bn;

b1=a1,b2=a2-a1,bi=ai-a(i-1);

而等價於ai=b1+b2+……+bi=a1+a2-a1+……+ai-ai-1=ai;

所以可以得到序列b是a的差分序列,而序列a為b的字首和

結合上面所說,對a連續子串行進行加一減一操作可以轉化為對b[l]和b[r+1]進行操作。

求出差分序列之後,原問題可以轉化為將序列b從第二項開始到最後一項全部變為0的最小運算元和種數。

這是用到貪心策略,將乙個有正有負的序列進行加減最後變為0,而且題中不考慮實現過程,只要求最後結果。最小運算元就是將正數進行減操作,負數進行加操作,在[2,n]區間中任取乙個正數和乙個負數進行操作。最後序列剩下全正或者全負,此時種數就是剩下的數加0,相當於序列a變成的值可以為0~k,(k是剩餘序列b的和)

這裡再說一下最小運算元,因為之前我這裡就不是很明白,將正數減c操作就相當於序列a從當前位置一直到最後這個連續區間段都進行了c次減一操作,操作步數為c,而找乙個負數與正數搭配,相當於在正數與負數這個區間內進行c次減一或者加一操作。

最後最小的操作步數就是min(p,q)+abs(p-q),也就相當於max(p,q),種數就是abs(p-q)+1;p為序列b中正數和,q為負數和

**注意要用long long

#include using namespace std;

long long a[100010];

int main()

long long ans=max(p,q);

long long res=abs(p-q)+1;

cout

}

IncDec序列 差分 貪心

給定乙個長度為 n 的數列 a1,a2,an 每次可以選擇乙個區間 l,r 使下標在這個區間內的數都加一或者都減一。求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。第一行輸入正整數n。接下來n行,每行輸入乙個整數,第i 1行的整數代表ai。第...

差分 貪心 IncDec序列

原題 題目描述 給定乙個長度為 n 的數列 a1,a2,ana1,a2,an,每次可以選擇乙個區間 l,r l,r 使下標在這個區間內的數都加一或者都減一。求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。輸入格式 第一行輸入正整數n。接下來n...

100 IncDec序列 差分 貪心

用途 主要用於給某一區間 加乙個數,或減乙個數 o 1 的時間內完成 差分,實際上就是字首和的逆過程,例如 已知字首和陣列 b,那麼它的差分陣列 a a1 b1 a2 b2 b1 a3 b3 b2 a4 b4 b3 an bn bn 1 如果把它們相加就很容易看出 a1 a2 a3 a4 an bn...