題意:
給定乙個長度為 n 的數列 a1,a2,…,an,,每次可以選擇乙個區間 [l,r],使下標在這個區間內的數都加一或者都減一。
求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。
分析:每次任意選兩個數,乙個加上1,另外乙個減去1
把b[2]到b[n]都變成0
情況1:2<=i,j<=n
,選b[i]和b[j]
這樣會改變b[2],b[3]…b[n]中兩個數的值,盡量多用(最好)【一正一負】
情況2:i=1,2<=j<=n
選b[j]和b[1],對某個字首進行操作(次之)【兩正】
情況3:2<=i<=n,j=n+1
對某個字尾進行操作(次之)【兩負】
情況4:i=1,n=n+1
對某個序列都進行操作(直接不用)
先算一下正數和負數的和
最小的操作次數就等於正數和負數的絕對值的和的最小值,再加上正數和負數的絕對值的差
方案數就是正數和負數的絕對值的差加上1
ac code:
#include
using
namespace std;
int a[
100005];
intmain()
//輸入
for(
int i=n;i>=
2;i--
)//為了保證a[i-1]是原數,而不是差分值
//求差分
long
long pos =
0, neg=0;
//pos=正數,neg=負數
for(
int i=
2;i<=n;i++
)else
//當是負數時
}//核心
cout<<
min(pos,neg)
+abs
(pos-neg)
/最小的操作次數就等於正數和負數的絕對值的和的最小值,再加上正數和負數的絕對值的差
cout<<
abs(pos-neg)+1
/方案數就是正數和負數的絕對值的差加上1
return0;
}
增減序列(IncDec序列)
題目 給定乙個長度為 n 的數列 a1,a2,an,每次可以選擇乙個區間 l,r 使下標在這個區間內的數都加一或者都減一。求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。輸入格式 第一行輸入正整數n。接下來n行,每行輸入乙個整數,第i 1行的...
100 增減序列
求出 a 的差分序列 b,其中 b1 a1,bi ai ai 1 2 i n 令 bn 1 0。題目對序列 a 的操作,相當於每次可以選出 b1,b2,bn 1 中的任意兩個數,乙個加一,另乙個減一。目標是把 b2,b3,bn 變為全零。最終得到的數列 a 就是由 n 個 b1 構成的。從 b1,b...
AcWing 100 增減序列
給定乙個長度為 nn 的數列 a1,a2,ana1,a2,an,每次可以選擇乙個區間 l,r 使下標在這個區間內的數都加一或者都減一。求至少需要多少次操作才能使數列中的所有數都一樣,並求出在保證最少次數的前提下,最終得到的數列可能有多少種。輸入格式 第一行輸入正整數nn。接下來nn行,每行輸入乙個整...