神仙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 #includeview codeusing
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;
}
(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 使用與位置無關的 進行編譯。生成共享庫時使用該選項編譯原始檔。對全域性資料的每個引用都生成為全域性偏移表中...