求 \(1\sim n\) 的排列,有 \(m\) 個限制條件,第\(i\)個限制條件 \(p_i\) 表示前 \(p_i\) 個數不能是 \(1\sim p_i\) 的排列,求符合要求的排列的個數。 答案對 20000311 取模。
\(n\le 2000,m,p_i
設\(dp[i][j]\)為滿足限制的情況下放好了排列的前\(i\)個數且最大值為\(j\)的方案數,轉移如下:
複雜度為\(o(n^2)\)。
設\(dp[i]\)為放置前\(p[i]\)個數滿足前\(i-1\)個限制,但是不滿足第\(i\)個限制的方案數。
\(dp[i]=p[i]!-\sum_^dp[j] \cdot (p[i]-p[j])!\),\(p[i]!\)為放置前\(p[i]\)個數不滿足第\(i\)個限制的方案數,對於\(j,減去放置前\(p[i]\)個數滿足前\(j-1\)個限制不滿足第\(j\)個限制的所有方案數\(dp[j]\cdot (p[i]-p[j])!\),\((p[i]-p[j])!\)表示從\(p[j]\)到\(p[i]\)的位置可以隨意放,這樣就可以不重複的計算出\(dp[i]\),在最後加乙個\(p[i]=n\)的限制,最後輸出\(dp[m]\)即可。
複雜度為\(o(m^2)\)。
#include using namespace std;
const int n=2e3+10;
const int mod=20000311;
typedef long long ll;
ll dp[n][n],f[n];
int n,m,p[n];
int main()
for(int i=1;i<=n;i++)
}printf("%lld\n",dp[n][n]);
return 0;
}
#include#define rep(i,x,n) for(int i=x;i<=n;i++)
#define per(i,n,x) for(int i=n;i>=x;i--)
#define ll long long
using namespace std;
const int mod=20000311;
const int n=1e5+10;
int n,m;
int p[n],f[n],dp[n];
int main()
f[0]=1;
rep(i,1,n) f[i]=1ll*f[i-1]*i%mod;
p[++m]=n;
sort(p+1,p+m+1);
for(int i=1;i<=m;i++)
printf("%d\n",dp[m]);
return 0;
}
牛客練習賽71 C 數學考試
時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 牛牛在樹剖姐姐的數學考試裡出了乙個題,但是樹剖姐姐不會做,於是她向您求助。求 1 sim n1 n 的排列,有 m 個限制條件,第i個限制條件 p ipi 表示前 ...
牛客練習賽71 C 數學考試
link 題意 求長度為n的排列有多少個 要求滿足 m個條件 pi 表示前pi個數不是1 pi的全排列 m第一次遇到這樣的dp狀態 很奇妙。它是通過列舉最後乙個不滿足條件的位置來得到答案,所以不會減重複。學到了 2 常規dp,dp i j 表示第i個位置以及之前的數最大值為j的方案數,那麼對於限制條...
(概率dp)牛客練習賽39 C
現在一共有n天,第i天如果有流星雨的話,會有wi顆流星雨。第i天有流星雨的概率是pi。如果第一天有流星雨了,那麼第二天有流星雨的可能性是p2 p,否則是p2。相應的,如果第i 1 i 2 天有流星雨,第i天有流星雨的可能是pi p,否則是pi。求n天後,流星雨顆數的期望。因為當天的概率只與前一天的概...