給定乙個長度為 n 的數列 a1,a2,…,an,每次可以選擇乙個區間 [l,r],使下標在這個區間內的數都加一或者都減一。
求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。
第一行輸入正整數n。
接下來n行,每行輸入乙個整數,第i+1行的整數代表ai。
第一行輸出最少操作次數。
第二行輸出最終能得到多少種結果。041
1221
2差分:與字首和互逆
設原陣列為a[1
],a[
2]…a
[n
]a[1],a[2]…a[n]
a[1],a
[2]…
a[n]
定義差分b[i
]=a[
i]−a
[i−1
],b[
1]=a
[1
]b[i] = a[i] - a[i-1], b[1] = a[1]
b[i]=a
[i]−
a[i−
1],b
[1]=
a[1]有a[
i]=b
[1]+
b[2]
+…+b
[i
]a[i] = b[1] + b[2] + … + b[i]
a[i]=b
[1]+
b[2]
+…+b
[i]即,若b為陣列a的差分序列,則a是b的字首和序列
和字首和類似,差分的作用是把區間操作變為單點操作。
思路:因為只是+1,-1,所以不需要線段樹或樹狀陣列
本題要求讓陣列a全相同,可以轉化為所有數的差分為0
解題步驟:
對原陣列a1…an求差分序列b1…bn
如果要給區間[l,r] 加 c ,可以通過對查分陣列進行b[l] += c
、b[r+1] -= c
兩步單點操作實現。
此後當我們再求原陣列時,因為原陣列是差分序列的字首和,在求a[0]…a[l-1]時,因為差分b[0]…b[l-1]都沒變,所以a[0]…a[l-1]也沒變。
在求a[l]…a[r]時,因為差分b[l] += c
,所以a[l]…a[r]都加了c。
在求a[r+1]…a[n]時,因為差分b[l]+=c
,b[r]-=c
,所以a[r+1]…a[n]沒變。
總結: 對陣列中乙個區間的加c與減c,可以轉換為區間端點的差分加c與減c。
對於本題:如果可以經過n次運算使差分序列全部變為0,則陣列也可以通過這n次運算變為相同的數。
如陣列a: 1 1 2 2 1
其差分b:(1)0 1 0 -1
要讓a[3]…a[4]這段區間(差分的字首和)減1,使其全部元素相等,
等價於讓b[3]-=1, b[5] +=1即可。
進一步考慮,b[3]原本是正數,b[5]原本是負數。
我們的最終目的是讓b陣列的每個數都變為0,我們的每次操作最多可以讓b陣列的兩個數乙個+1,乙個-1。(這兩個數分別是區間的兩個端點,可以任意選)。 這裡的最多是因為也可以只讓1個數+1或-1。基於貪心的思想,我們會先將正數與負數相抵消,最後剩下只有正數或只有負數的時候再單獨處理正數與負數。
第一問:每次最多只能同時把差分陣列b的乙個數+1,乙個數-1, 問把pos個+1和neg個-1都變為0需要幾步。
最小步數:min
(pos
,neg
)+ab
s(po
s−ne
g)
min(pos, neg) + abs(pos - neg)
min(po
s,ne
g)+a
bs(p
os−n
eg)
第二問 :最終得到的數列可能有多少種
有a bs
(pos
−neg
)+
1abs(pos - neg) + 1
abs(po
s−ne
g)+1
種匹配方式
#include
#include
using namespace std;
typedef
long
long ll;
const
int n =
100010
;int a[n]
;int
main()
cout <<
min(pos, neg)
+abs
(pos - neg)
<< endl;
cout <<
abs(pos - neg)+1
<< endl;
return0;
}
《演算法競賽高階指南》 防曬
有c頭奶牛進行日光浴,第i頭奶牛需要minspf i 到maxspf i 單位強度之間的陽光。每頭奶牛在日光浴前必須塗防曬霜,防曬霜有l種,塗上第i種之後,身體接收到的陽光強度就會穩定為spf i 第i種防曬霜有cover i 瓶。求最多可以滿足多少頭奶牛進行日光浴。輸入格式 第一行輸入整數c和l。...
《演算法競賽高階指南》蚯蚓
蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去請神刀手來幫他們消滅蚯蚓。蛐蛐國裡現在共有 n 只蚯蚓,第 i 只蚯蚓的長度為 ai 所有蚯蚓的長度都是非負整數,即可能存在長度為0的蚯蚓。每一秒,神刀手會在所有的蚯蚓中,準確地找到最長的那乙隻,將其切成兩段。若有多隻最長的,則任...
演算法競賽高階指南筆記
原碼 原碼就是符號位加上真值的絕對值,即用第一位表示符號,其餘位表示值.比如如果是8位二進位制 其中,第一位為1是負數 1 0000 0001 原 1 1000 0001 原 因此,8位二進位制數的取值範圍 127,127 補碼正數的補碼是其本身 負數的補碼是在其原碼的基礎上,符號位不變,其餘各位取...