bzoj
首先我們如果確定了乙個不降序列,假設它的長度為
i i
, 那麼可行的方案數為i∗
(n−i
)!' role="presentation">i∗(
n−i)
!i∗(
n−i)
!,但是這樣有一些非法的情況,即刪掉最後乙個數之前已經是有序的了。
那麼設g[i
] g[i
]表示長度為
i i
的不降序列的總數
因為所有長度為
i' role="presentation">i
i的不降序列一定包含在長度為i+
1 i+1
的不降序列之中
如果先構成了乙個長度為i+
1 i+1
的不降序列,再刪掉了一位,那麼這樣是不合法的。
所以長度為
i i
的不降序列的貢獻為: g[
i]∗(
n−i)
!−g[
i+1]
∗(n−
i−1)
!∗(i
+1)' role="presentation">g[i
]∗(n
−i)!
−g[i
+1]∗
(n−i
−1)!
∗(i+
1)g[
i]∗(
n−i)
!−g[
i+1]
∗(n−
i−1)
!∗(i
+1)即先構成了乙個長度為i+
1 i+1
的不降序列,再列舉刪去了哪個數構成了長度為
i i
的不降序列。 至於i
' role="presentation">i
i怎麼算,可以設f[
i][j
] f[i
][j]
表示以i i
結尾,長度為
j' role="presentation">j
j的不降序列的個數 f[
i][j
]=∑f
[k][
j−1]
(a[k
]≤a[
i]) f[i
][j]
=∑f[
k][j
−1](
a[k]
≤a[i
])
樹狀陣列優化一下就好了
時間複雜度o(
n2lo
gn) o(n
2log
n)
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define ll long long
#define rg register
#define max 2002
#define mod 1000000007
inline
int read()
void add(int &x,int y)
int a[max],n,s[max],len;
int f[max][max],g[max];
int c[max],jc[max],ans;
int lb(int x)
void modify(int x,int w)
int getsum(int x)
int main()
}add(ans,g[n]);
for(int i=n-1;i;--i)
add(ans,(1ll*g[i]*jc[n-i]%mod-1ll*g[i+1]*jc[n-i-1]%mod*(i+1)%mod+mod)%mod);
printf("%d\n",ans);
}
bzoj4361 isn(樹狀陣列優化dp 容斥)
time limit 10 sec memory limit 256 mb submit 938 solved 485 submit status discuss 給出乙個長度為n的序列a a1,a2.an 如果序列a不是非降的,你必須從中刪去乙個數,這一操作,直到a非降為止。求有多少種不同的操作方...
BZOJ1037動態規劃
資料範圍很小,可以用4維儲存下前i個男孩j個女孩,從這一位往前的所有點中男 女的差最大為x,女 男為y的方案數 主動遞推 f i 1 j x 1 max y 1 0 f i j x y f i j 1 max x 1 0 y 1 f i j x y 最後答案為 sigma x sigma y f n...
BZOJ1040 騎士(動態規劃)
bzoj 對於每一組厭惡的關係 顯然是連邊操作 如果是一棵樹的話 很顯然的樹型dp 但是,現在相當於有很多個基環 也就是在一棵樹的基礎上再加了一條邊 這個時候怎麼辦,暴力拆掉基環 拆掉任意一條邊 跑兩遍dp 計算出強制不選兩個點中某乙個的最大值 此時就是這個基環的最大值 不用拆掉所有的邊,因為只要拆...