題目描述
乙個序列的第1,3,5…項被稱作奇數項,第2,4,6…項被稱作偶數項。乙個序列a[1…n]被稱作zigzag序列當且僅當以下兩個條件中的乙個(或兩個)成立: 1)除了首項,所有的奇數項都比它的前項小且所有的偶數項都比它的前項大。 2)除了首項,所有的奇數項都比它的前項大且所有的偶數項都比它的前項小。乙個序列a[1…n]被稱作k凹凸序列當且僅當它的最長zigzag子串行(不一定是連續子串行)的長度不超過k。現在有乙個序列a[1…n],每次可以花費1的代價使得a中的某一項增加或減少1。我們的目的是花費最少的代價讓它成為k凹凸序列。輸入的第一行包含兩個正整數,分別表示數列a[1…n]的長度n和k。接下來的n行每行乙個自然整數,依次表示數列的項。
資料範圍
前1個測試點滿足:k=1,n≤20000
第2~8個測試點滿足:k=2,n≤20000
第9~15個測試點滿足:k=3,n≤20000
第16~20個測試點滿足:k≤10,n≤1000
所有測試點滿足:a[i]≤50000
首先需要理解這種子串行就是一大一小(也就是凹凸
的),觀察資料範圍,不難發現本題需要資料分治。
k =1
k=1k=
1,最簡單的一種情況,把所有數都變成中位數。
k =2
k=2k=
2,整個序列必須是單調不減/
//單調不增的,就變成了這道題 k=3
k=3k=
3,一定有乙個轉折點,使得前面單調不減,後面單調不增/
//前面單調不增,後面單調不減,那麼我們就列舉轉折點,可以用k=2
k=2k=
2的方法預處理改變的花費,但由於我們要知道每個位置的花費,我們維護每個區間的和s
ss,在左偏樹上的和hshs
hs,還記錄上一次合併的花費,由絕對值的幾何意義知道這個區間新的花費是s−2
hs
s-2hs
s−2h
s,然後還要特殊考慮區間長度為奇數的情況,要出去中位數的影響(再加上乙個中位數),這一部分可以結合**理解。
k =4
k=4k=
4,發現此時n
≤1000
n\le1000
n≤1000
,用k =3
k=3k=
3的方法預處理把每個區間變成單調不增/
//單調不減的花費,然後就有乙個很顯然的dpdp
dp了,最後要求出把原序列劃分成k−1
k-1k−
1個單調段的最小花費,o(n
2k
)o(n^2k)
o(n2k)
暴力d pdp
dp不解釋。
至於**,emm
memmm
emmm
,應該還能夠接受吧,就是調得有點久,有幾個我遇到的坑點寫了注釋。
#include
#include
#include
#include
using
namespace std;
#define ll long long
const
int n =
1005
;const
int m =
20005
;int
read()
int n,m,k,ans,a[m]
,ch[m][2
],dis[m]
,rt[m]
,siz[m]
;int cost[m]
,e[m]
,s[m]
,hs[m]
,lu[m]
,ld[m]
,ru[m]
,rd[m]
;int up[n]
[n],dw[n]
[n],fu[n][15
],fd[n][15
];intmerge
(int x,
int y)
void
adjust()
}int
abs(
int x)
intwork
(int r[m]
,int x=1)
}return r[n];}
void
work1()
void
work2()
void
work3()
void
work4()
for(
int i=
1;i<=n;i++
)memset
(fu,
0x3f
,sizeof fu)
;memset
(fd,
0x3f
,sizeof fd)
; fu[0]
[0]=fd[0]
[0]=
0;for(
int i=
1;i<=n;i++
)for
(int l=
1;l<=k;l++
)for
(int j=
0;j) ans=
0x3f3f3f3f
;for
(int l=
1;l)//要注意不一定是k最優喲
//一開始寫成<=k調了好久
ans=
min(ans,
min(fu[n]
[l],fd[n]
[l]));
printf
("%d\n"
,ans);}
intmain()
BZOJ 3110, K大數查詢
傳送門 要求維護乙個數列,支援在某部分的每個位置填上乙個數以及查詢某部分第k大的數字。終於學習了一下樹套樹的姿勢 其實和自己想的也差不多 但是不學還是打不出 來 外層是權值線段樹,內層是區間線段樹。要注意的細節比較多。二分查詢過程中結果可能超過maxlongint,需要用unsigned int型別...
BZOJ1073 k短路(A 演算法)
a 演算法,也叫啟發式搜尋,就是設計乙個預估函式,然後在搜尋的過程中進行有序的搜尋,我們設到目前狀態的花費為f x 到目標狀態的估計花費為h x 那麼我們按照h x f x 排序即可,這道題裡起點到目前的距離為f x 目前到終點的最短路為g x 然後進行暴力搜尋即可。by vane includeu...
K大數查詢(bzoj 3110)
有n個位置,m個操作。操作有兩種,每次操作如果是1 a b c的形式表示在第a個位置到第b個位置,每個位置加入乙個數c 如果是2 a b c形式,表示詢問從第a個位置到第b個位置,第c大的數是多少。第一行n,m 接下來m行,每行形如1 a b c或2 a b c 輸出每個詢問的結果 2 51 1 2...