WOJ 10 精英選拔

2022-06-13 04:39:13 字數 1405 閱讀 8335

神仙dp,膜claris

題意:給乙個長度為$n$的數列,求出不超過k次交換後的最大連續子區間和。

發現交換後的最優答案一定是這樣的(0和2的長度可以為0)

0           (    1    )         2            

答案是標號為1的區間和。

那麼就相當於在原數列中下標在0或2的數字可以放入1中,而原來下標在1的數可以拿出來到0或2。

我們設$f_$表示現在到第$i$個數,現在劃分到的集合已經屬於$0/1/2$,其中$0/2$中的數有$a$個被放入1中,$1$中的數有$b$個放入了$0/2$中的最優答案,那麼最後的答案$ans = max_(f_)$

然後題解裡面就出現了轉移方程顯然這六個字……

喂,轉移方程不顯然啊……

對於每乙個數有保留在原集合和放入$1/(0,2)$中兩種放法。

我們只關心有多少數被放入了1,因為這是最後的答案,那麼i到i + 1應當可以直接轉移,這中間還對應著集合的變化。

對於要放入1的數,應當使$a$轉移到$a + 1$

對於從1中拿出來的數,應當使$b$轉移到$b + 1$

具體還是參照**實現吧(感覺還是和沒說一樣),時間複雜度$o(nk^)$,在$k$較小的時候有比較優秀的表現。

code:

#include #include 

using

namespace

std;

typedef

long

long

ll;const

int n = 1e4 + 5

;const

int m = 12

;const ll inf = (ll) 1

<< 60

;int

n, m, d[n];

ll f[n][

3][m][m];

inline

void read(int &x)

template

inline

void chkmax(t &x, t y)

intmain()

for(int i = 0; i < n; i++)

for(int a = 0; a <= m; a++)

for(int b = 0; b <= m; b++)

for(int i = 0; i < n; i++)

for(int a = 0; a <= m; a++)

for(int b = a; b <= m; b++)

ll ans =0ll;

for(int i = 0; i <= m; i++)

printf(

"%lld\n

", ans);

return0;

}

view code

(10)動態選路協議

一 簡介 動態選路協議用於路由器間的通訊。二 rip 選路資訊協議 rip報文包含在udp資料報中。如下所示 rip常用的udp埠號是520。rip協議的routed程式正常執行過程如下 1 初始化 在啟動乙個路由守護程式時,它先判斷啟動了哪些介面,並在每個介面上傳送乙個請求報文,要求其他路由器傳送...

datagrid在MVC中的運用10 勾選

本文體驗與勾選有關的特性。需要載入的books.json 展開 檢視 展開 content themes default easyui.css rel stylesheet content themes icon.css rel stylesheet button id buttongetcheck...

Solaris10的CC編譯器部分編譯選項

g 生成動態共享庫而不是可執行檔案 在有了這個選項的時候,必須指定鏈結時需要的庫,編譯器不會鏈結任何預設的庫 gcc下面對應的選項是 shared i 指定標頭檔案搜尋路徑 kpic kpic 使用與位置無關的 進行編譯。生成共享庫時使用該選項編譯原始檔。對全域性資料的每個引用都生成為全域性偏移表中...