APIO2020 粉刷牆壁

2022-04-29 05:48:08 字數 1126 閱讀 3682

考場想了 5.5 h,第一部分分死活打不出來,做到崩盤,現在重做,感覺自己就是乙個sb,放學在地鐵上一眼就會了。哎。

可以把乙個要求看作乙個長度為 \(m\) 的區間:\([l, l + m - 1]\),可以要求這段條件的充要條件是找到一種迴圈移位,每個牆恰好可以被那個工人挖。然後問題是用最少的區間覆蓋完 \([0, n - 1]\)。

可以設乙個 dp:

$f_i $:刷完前 \(i\) 個牆的最小要求次數。

這個東西顯然是乙個滑動視窗最值,用單調佇列優化,我們現在的就要求快速判斷 \([i - m + 1, i]\) 能不能刷。

設 \(len_\) 為第 \(i\) 個牆,第 \(j\) 個人刷,最多可以迴圈移位向前延伸多少個。

對於乙個 \(i\),列舉 \(c_i\) 顏色對應的所有的工人 \(u\),轉移 \(len_ = len_ + 1\)。

由於 \(\sum f(k)^2 \le 400000\),所以 \(f(k)\) 是 \(600\) 量級的,時間複雜度是 \(o(n \max(f(k)))\) 是可以過的。

但是空間不夠,滾動陣列就好了,但是還要保證轉移的是 \(i - 1\) 次,所以每次轉移賦值 \(g_ = i\),表示這個迴圈移位最後的位置是 \(i\)。轉移判斷上次的是不是 \(i - 1\) 就行了。

單調佇列還有一些細節,比如正無窮不能扔進佇列之類。

#include #include #include using namespace std;

const int n = 100005, m = 50005, inf = 0x3f3f3f3f;

int f[n], q[n], g[2][m], len[2][m];

vectord[n];

int minimuminstructions(

int n, int m, int k, std::vectorc,

std::vectora, std::vector> b)

}int hh = 0, tt = -1;

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

if (ok) }}

return f[n - 1] == inf ? -1 : f[n - 1];

}

2 02 理解查詢模型

示例 select name from users where age 10 可以形象的看作是下面這樣 let arr let users users.foreach item 是指列與列之間進行運算得出的結果,叫做廣義投影 因為null 表達的意思是 空 null null false null ...

CI20 2 洗牌演算法

實現乙個方法,對一副牌 52張 進行洗牌,要求洗出的52 組合是的等概率的,即每種組合的概率為1 52 假設已經有乙個完美的隨機數生成器。思路 思路比較直觀,第一次從52張牌中隨機取一張出來,概率為1 52 第二次從剩下的51張隨機取一張出來,概率為1 51 以此類推最終的概率就是1 52 接下來是...

axp202電源管理

問題 充電電流被限制,導致充電時間過長。版本分支 android4.3 master 復現問題,檢測電流變化,發現機器在深度休眠後電流會由原來的1.2a變成0.5a。猜測 可能是由於充電電流過小導致充電時間過長。echo 30 sys class axppower axpreg cat sys cl...