校內模擬 拯救(遞推)

2021-07-24 16:19:38 字數 1343 閱讀 1733

這題年代可久遠了。。似乎是今年寒假還是什麼時候loli的測試題來著?反正atp當時太水了不會做。。。現在越看越覺得當時很蛋疼= =

不過看這個題目的話,首先它的目標狀態是把所有的都變成0,所以會有乙個f[i]表示把前i個都變成0所需要的最少步數;其次,它要改變第i個點的狀態一定是把前i-2個變成0並且把第i-1個變成1,這種狀態我們稱為對於點i的「可修改狀態」,那麼就再設乙個g[i]表示把前i個字元變成對於點i+1的「可修改狀態」所需要的最少步數。

那麼對於f[i]的遞推,分成第i個字元是0還是1兩種情況來討論。如果第i個字元是0的話,那f[i]可以直接繼承f[i-1]的結果;如果第i個字元是1的話,那就要先把前i-1個字元變成對於點i的「可修改狀態」,就是g[i];然後再把第i個字元變成0,就加一;然後還要把前i-1個字元變回去。把前i個字元從「可修改狀態」變成全是0的狀態這個可以直接用式子算出來。很容易得到遞推公式就是k1

=1,k

i=2∗

ki−1

+1,那麼ki

=2i−

1 。

對於g[i],如果第i個字元是1的話那直接就是f[i-1],否則要先把前i-1個變成「可修改狀態」,就是g[i-1],然後改一下第i個再把前i-1個還原,和上面說的f[i]的第二種情況是一樣的。

總的來說就是:f[

i]=⎧

⎩⎨f[

i−1]

,g[i

−1]+

1+2i

−1,a[i]=0

a[i]=1 g

[i]=

⎧⎩⎨f

[i−1

],g[

i−1]

+1+2

i−1,

a[i]=1

a[i]=0

誒好像f和g兩個陣列就是倒過來倒過去的啊,所以是不是可以搞到一起去啊。

#include

#include

#include

#define inc(x)(x=(x%200000)+1)

using

namespace

std;

int n,a[1010];

long

long f[1010],g[1010];

int main()

else

printf("%i64d\n",f[n]);

return

0;}

拯救LongMM (遞推公式求解)

拯救l o n g m m l a n p a s c c p p 題目描述 longdd 將軍為了平息延續數年戰亂,決定釋放戰俘營中所有的俘虜。然而,longdd 將軍不打算釋放敵軍的統帥longmm 因為這個傢伙異常聰明,是個難纏的 對手。所以longdd 將軍決定把longmm 用鍊子固定到牆...

校內模擬 鎖

沒有標籤是因為我真的不知道這算什麼型別 這題我說不來大意你們還是看題面描述吧 小z住的房子一共有n個人,他們每人有乙個重要度。房子的門上可以裝若干把鎖。假設共有k把鎖,命名為1到k。每把鎖有一種對應的鑰匙,也用1到k表示。鑰匙可以複製若干份並發給任意多個居民。每個人都可以持有若干鑰匙,可以不持有鑰匙...

校內模擬 assignment(DP)

題面見校內oj4693 考慮預處理f k i j f k i j f k i j 表示最長的一段不超過k kk的時候,將長度為i ii的序列分為j jj段的方案數。在k kk相同的狀態之間轉移,顯然有f i j f i 1 j f i 1 j 1 f i k 1 j 1 f i j f i 1 j ...