你正在玩乙個關於長度為 \(n\) 的非負整數序列的遊戲。這個遊戲中你需要把序列分成 \(k + 1\) 個非空的塊。為了得到 \(k + 1\) 塊,你需要重複下面的操作 \(k\) 次:
選擇乙個有超過乙個元素的塊(初始時你只有一塊,即整個序列)
選擇兩個相鄰元素把這個塊從中間分開,得到兩個非空的塊。
每次操作後你將獲得那兩個新產生的塊的元素和的乘積的分數。你想要最大化最後的總得分。
第一行包含兩個整數 \(n\) 和 \(k\)。保證 \(k + 1 \leq n\)。
第二行包含 \(n\) 個非負整數 \(a_1, a_2, \cdots, a_n\) (\(0 \leq a_i \leq 10^4\)),表示前文所述的序列。
第一行輸出你能獲得的最大總得分。
第二行輸出 \(k\) 個介於 \(1\) 到 \(n - 1\) 之間的整數,表示為了使得總得分最大,你每次操作中分開兩個塊的位置。第 \(i\) 個整數 \(s_i\) 表示第 \(i\) 次操作將在 \(s_i\) 和 \(s_\) 之間把塊分開。
如果有多種方案使得總得分最大,輸出任意一種方案即可。
第乙個子任務共 \(11\) 分,滿足 \(1 \leq k < n \leq 10\)。
第二個子任務共 \(11\) 分,滿足 \(1 \leq k < n \leq 50\)。
第三個子任務共 \(11\) 分,滿足 \(1 \leq k < n \leq 200\)。
第四個子任務共 \(17\) 分,滿足 \(2 \leq n \leq 1000, 1 \leq k \leq \min\\)。
第五個子任務共 \(21\) 分,滿足 \(2 \leq n \leq 10000, 1 \leq k \leq \min\\)。
第六個子任務共 \(29\) 分,滿足 \(2 \leq n \leq 100000, 1 \leq k \leq \min\\)。
首先可以通過數學歸納法證明: 只要切割位置相同, 切割順序不會影響答案.
首先有乙個 \(拿衣服\) 的想法 直接想到正解的大佬可以跳過:
用 \(i\) 表示當前的位置, \(k\) 表示切割的次數, 列舉之前的每乙個狀態 \(j\).
\[f\left(i, k\right) = \max\left\, j \in \left[1, i-1\right]
\] 但是由於它太 \(拿衣服\) 了, 所以不好處理(實際可做).
反向考慮整個序列, 轉移方程變形為:
\[f\left(i, k\right) = \max\left\, j \in \left[1, i-1\right]
\]看資料 \(1e6\), \(o\left(n^2k\right)\) 顯然不可做, 憑感覺考慮斜率優化
設 \(f\left(i, k\right) = f(i)\), $f\left(i, k-1\right) = g(i) $ , 進行移項, 有:
\[g\left(j\right) - s^2\left(j\right) = -s\left(i\right)s\left(j\right) + f\left(i\right)
\] 斜率 \(-s(i)\) 單調遞減.
考慮當前決策 \(j\) 和前乙個決策 \(j-1\), 若 \(j\) 優於 \(j-1\), 有:
\[k = \frac \gt -s(i)
\]即:
\[\frac \le s(i)
\]然後就可以大力斜率優化並wa掉
注意乙個細節: \(a_i\) 可能為 \(0\), 上式的分母可能為 \(0\), 需要在程式中特判一下.
**:
# include # include # include # define ll long long
# define maxn 1000005
using namespace std;
ll a[maxn], sum[maxn];
ll f[maxn][2];
int sol[maxn][205]; // 記錄轉移順序
int q[maxn];
double slope(int i,int j, int g)
int main()
for(int k = 0, lim = 1; lim <= s; k^=1, lim++)
f[i][k] = f[q[l]][g]+sum[q[l]]*(sum[i]-sum[q[l]]);
sol[i][lim] = q[l];
while(l < r && slope(q[r-1],q[r], g)>=slope(q[r],i, g))
q[++r] = i;
} }printf("%lld\n", max(f[n][1], f[n][0]));
for(int x=n,i=s;i>=1;--i)
return 0;
}
時間複雜度: \(o(nk)\)
玄學 \(1\): 最開始寫的deque
的時候莫名其妙赤橙黃綠青藍紫, 改手寫單調佇列就過了 估計是我哪寫錯了
玄學 \(2\): 本來打算移項逃避精度問題的, 結果鍋掉 估計就是式子移錯了
APIO2014 序列分割 斜率優化DP
apio2014 序列分割 題目大意 你正在玩乙個關於長度為 n 的非負整數序列的遊戲。這個遊戲中你需要把序列分成 k 1 個非空的塊。為了得到 k 1 塊,你需要重複下面的操作 k 次 選擇乙個有超過乙個元素的塊 初始時你只有一塊,即整個序列 選擇兩個相鄰元素把這個塊從中間分開,得到兩個非空的塊。...
NOI2014 購票 樹上斜率優化
首先易得方程,且經過變換有 begin f i min limits f j p idist j f i dist ip i q i end 在一條直線上時,斜率優化可以用普通 cdq 分治實現 會不會過於麻煩?那麼對於在樹上斜率優化時,考慮點分治 這時就在點分治中運用 cdq 分治的思想,即使用在...
NOI2014 購票(樹形dp 樹剖 斜率優化)
考慮樹形 dp,設 dpi dp i dpi 為 ii i 節點到 sz 市的最小費用,dis idis i disi 為 sz 市到 i ii 節點的距離。顯然初始化 dp1 0 dp 1 0 dp1 0 然後 dis idis i disi 可以提前預處理出來。然後有 dpu min dpv d...