問題描述
現在要給n個小朋友發蘋果,每乙個小朋友都會有自己相應的蘋果數目 ,,, \cdots a題意即乙個序列的所有不同排列的總和,乙個序列的和如上所述。1,
a2
,a
3,
⋯an
。 發蘋果的時候,小朋友先從左到右隨機站成一排。設站好後從左到右小朋友的標號是 ,,, \cdots p
1,
p2
,p
3,
⋯pn
,他們所需要的蘋果數目是 }},}},}}, \cdots }}a
p1
,
ap
2
,a
p3
,
⋯ap
n
,對於最左邊的人要給他發 }}a
p1
個蘋果,對於第i (i>1)個人,如果前面有乙個人的蘋果要求的數目比他多,那麼就不用發給他蘋果,否則發給他 }}a
pi
個蘋果。那麼對於某乙個排列需要多少蘋果就可以計算出來了。現在我們想知道對於所有的排列總共要發多少蘋果。兩個排列不一樣當且僅當至少存在乙個位置要求的蘋果數目不一樣。
分開計算每個值得貢獻,如j個i的所有方案數的總和。那裡乘c(n,n-sum[i-1])非常妙。
#include#include#include#include#include#include#include#include#include#include#include#include#include#define fi first
#define se second
#define ll long long
#define pii pair#define inf (1<<30)
#define eps 1e-8
#define pb push_back
using namespace std;
const int maxn=110005;
const ll mod=1000000007;
ll jiech[maxn];
ll inv[maxn];
int n;
int d[maxn];
int dis[maxn];
int num[maxn];
int p[maxn];
int sum[maxn];
ll tot[maxn];
ll tui[maxn];
ll powmod(ll a,ll b)
void pre()
ll c(int a,int b)
int main()
sort(dis,dis+n);
int k=unique(dis,dis+n)-dis;
for(int i=1;i<=n;i++)
sum[0]=0;
for(int i=1;i<=k;i++)
sum[i]=sum[i-1]+num[i];
tot[0]=1;
for(int i=1;i<=k;i++)
tot[i]=tot[i-1]*inv[num[i]]%mod;
tui[k+1]=1;
for(int i=k;i>=1;i--)
tui[i]=tui[i+1]*inv[num[i]]%mod;
ll ans=0;
for(int i=1;i<=k;i++)
}printf("case #%d: %i64d\n",cas++,ans);
}return 0;
}
hdu 1799 DFS求組合數
problem description 我們知道,在程式設計中,我們時常需要考慮到時間複雜度,特別是對於迴圈的部分。例如,如果 中出現 for i 1 i n i op 那麼做了n次op運算,如果 中出現 fori 1 i n i for j i 1 j n j op 那麼做了n n 1 2 次op...
hdu 1220 Cube 組合數學
給你乙個邊長n的正方體,切割成n n n個單位體積的小正方體,求所有公共頂點數 2的小正方體的對數。公共點的數目可能有 0,1,2,4.我們用總的對數減掉有四個公共點的對數就可以了。總的對數 n 3 n 3 1 2 一共有n 3塊小方塊,從中選出2塊 而4個交點的立方體對是兩個立方體共面的情況,所以...
思路 組合數 hdu 3398 String
題意 給你n個1和m個0,讓你拼成n m長度的並且所有字首的1都不少於0的個數的串,問有多少種方法。思路 將構造字串的過程轉化到二維座標上去,1用y表示,0用x表示,從座標 0,0 出發,0代表向右走 x增加 1代表向上走 y增加 因為0有m個,1有n個,所以最後到達的座標為 m,n 單純考慮從0,...