bzoj1584 打掃衛生 dp

2022-03-27 02:32:28 字數 910 閱讀 6580

題意:找到某種分割序列方法,使得每一段中所含數的種類平方之和最小。

考試時一時腦殘連暴力$dp$都沒寫出來……

首先暴力dp應該都寫得出來……$f[i]=min(f[j]+(cnt[j~i])^2)$

正解有個比較智障的優化……首先可以想到答案不會差過$n^2$(最差就是每乙個一段),因此,我們只需要記錄每段中有$1,2,3……sqrt(n)$個不同元素的情況,找到這些段開始的位置的前乙個位置,記作$pos[j]$,那麼,$f[i]=min(f[pos[j]]+j*j)$。

下面重點問題就變為$i$改變時如何修改$pos$陣列。為方便我們再記錄每種數字出現的上個位置$pre[j]$和每一段中有的數字種類$cnt[j]$。

首先,如果$pre[a[i]]<=pos[j]$,則$cnt[j]++$。

然後對於每乙個$cnt[j]>j$的情況,暴力右移左端點,如果這時$pre[a[pos[j]]]==pos[j]$,$cnt[j]--$。

問題得解。

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;

7const

int maxn=40005;8

inta[maxn],pos[maxn],cnt[maxn],pre[maxn],n,m,f[maxn];

9int

haha()

1025

for(int j=1;j<=num;j++)f[i]=min(f[i],f[pos[j]]+j*j);26}

27 printf("

%d\n

",f[n]);28}

29int sb=haha();

30int main()

bzoj1584

bzoj 5045 打磚塊 優先佇列

小q最近沉迷於一款新型 打磚塊 遊戲。在每局遊戲中,呈現在螢幕上的是一堵無限大小的牆壁。牆壁上鑲嵌著 無數長度為2 寬度為1的磚塊。牆壁被分成若干行,每行寬度都為1,相鄰兩個格仔形成乙個磚塊。相鄰兩行的磚 塊是間隔擺放的。牆壁從下往上行編號遞增,從左往右列編號遞增。如下圖所示 在遊戲的一開始,有n塊...

分塊打表 bzoj 3758 數數

題目描述 description 神犇最近閒來無事,於是就思考哲學,研究數字之美。在神犇看來,如果乙個數的各位能夠被分成兩個集合,而且這兩個集合裡的數的和相等,那麼這個數就是優美的 具體原因就只有神犇才知道了 現在神犇在思考另乙個問題,在區間 a,b 中有多少個數是優美的?這個問題對於神犇來說很簡單...

bzoj 3798 特殊的質數(分塊打表)

time limit 50 sec memory limit 128 mb submit 239 solved 119 submit status discuss 求 a,b 之間的質數個數,並且滿足x q 2 p 2,p,q是正整數。第一行輸入a,b 輸出有多少組p,q滿足條件 6 667 預處理...