DP ZROI 2017 提高3 T3 建築

2021-08-09 01:38:47 字數 1076 閱讀 9827

首先我們可以簡化一下條件,顯然只要滿足相鄰元素滿足限制即可。即對於任意的相鄰的 i,

j 滿足 ma

x>=|x

i−xj

| 考慮如果我們已經知道排列的順序,那麼我們很容易統計這種順序下的答案:設 s

=∑n−

1i=1

max ,則相當於選

n 個非負整數,加和不大於 x−

1−s的方案數。經典的隔板法得 方案數 (x

−1−s

+nn)

。s小於 n2

,現在我們需要對於每個

s 算出有幾種方案。可以 dp

,考慮從小到大不斷插入,現在插入的是當前的最大值,這樣比較好處理。f[

i][s

][j]

,j表示有

j個間隙待插入,

s 表示其他規定不再插入的位置對s的貢獻和。這樣轉移時就考慮插入後新多出來的空,是否規定不再插入。還有往邊界插的特殊情況需要考慮。

複雜度o(n

4)

#include

#include

#include

using namespace std;

typedef long long ll;

const int maxn=100105;

int n,m,mod,f[2][10105][115],ans;// f[i][s][j]

ll inv[maxn],fac[maxn],fac_inv[maxn];

ll c(int n,int

m)int main()

(f[(i&1)^1][s][j+1]+=f_now*2

%mod)%=mod;

(f[(i&1)^1][s+(i+1)][j]+=f_now*2

%mod)%=mod;}}

for(int

s=0;s

<=n*n&&s

<=m-n;s++) (ans+=c(m-s,n)*f[n&1][s][0]%mod)%=mod;

printf("%d\n",ans);

return

0;}

2023年8月10號提高組T3 樹

給你一棵大小為n的有根樹,每個點有點權,要求完成以下操作 v x y把點x的權值變成y e x把有根樹的根變為x q x查詢點x的子樹的最小值 第一行兩個整數n,m,表示點數和運算元。接下來n行,每行兩個數f,v,第i行的兩個數表示i的父親和i的權值,且保證f接下來m行,每行表示乙個操作。對於每個q...

2023年8月16日提高組T3 旅館

有一間旅館,旅館內有n間排成一排的房間,一開始全為空。現在有m個要求 1 d表示詢問旅館內是否有連續d間空房間,有的話則輸出最小的乙個r,滿足從r開始連續d間房間均為空,同時會有人入住這d間房。若無法被滿足,則輸出0.2 l r表示把 l,r 內的房間全部設為空。第一行兩個整數n,m.接下來m行,每...

2023年8月7日提高組T3 選數

給出n個數a i 現在可以在其中任意選出若干個數,問有多少種選擇方案,使得這幾個數可以分成兩個和相等的集合。第一行是乙個正整數n,第二行每行n個正整數。輸出乙個數,表示方案數。對於30 的資料,n 10.對於100 的資料,n 20,a i 100000000.by bpm 略難每個數字前可以填1 ...