題意:找到某種分割序列方法,使得每一段中所含數的種類平方之和最小。
考試時一時腦殘連暴力$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 #include6bzoj1584using
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()
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 預處理...