題意:給定兩個長度為n的互不相同的序列,將其兩兩配對,求有多少種配對使得a[i]>b[i]的對數減去其他對數恰好為k。
一道經典的計數題,但思路理清後發現並不算難。
首先設x為a[i]小於b[i]的對數。
x+x+k=n
2*x=n-k
所以當n-k為奇數,答案為0。
先令ne[i]表示小於a[i]的最後乙個b[j]的位置。首先考慮設f[i][j]表示到前i個糖果,有j個位置滿足配對,且不考慮後續情況。
轉移顯然為
$$f[i][j] = f[i-1][j]+f[i-1][j-1]*(ne[i]-j+1)$$
如果我們要考慮後續呢?
我們可以設g[i]表示只有i組糖果大於藥片
此時方程為
$$g[i] = f[n][i]*(n-i)!-\sum_^n g[j]*\dbinom$$
前者列舉對數形態而後者表示實際有j組數對但被統計到答案中去。
倒推即可。複雜度o(n^2)。
實際上筆者在寫**時g,f調換了順序。
#includeusing namespace std;
typedef long long ll;
int read()
while (ch>='0'&&ch<='9')
return x*f;
}const int mod=1e9+9;
int a[2005],b[2005],ne[2005];
ll f[2005],g[2005][2005],c[2005][2005],fac[2005];
int main()
for (int i=1;i<=n;i++)a[i]=read();
for (int i=1;i<=n;i++)b[i]=read();
sort(a+1,a+1+n); sort(b+1,b+1+n);
ne[0]=1;
k=(k+n)>>1;
for (int i=1;i<=n;i++)
} for (int i=0;i<=n;i++)
g[0][0]=1;
for (int i=1;i<=n;i++)
for (int j=0;j<=i;j++)
fac[0]=1;
for (int i=1;i<=n;i++)
fac[i]=(fac[i-1]*i)%mod;
for (int i=n;i>=k;i--)
printf("%lld\n",f[k]);
return 0;
}
bzoj 3622 已經沒有什麼好害怕的了
我好害怕這種題 兩個陣列排序後,處理出next i 表示滿足tang i yao j 的最大的j。f i j 前i種糖果,有j個糖比藥多,不考慮剩餘情況的方案數 也就是剩餘n j個糖果的放法算一種,最後乘上階乘。f i j f i 1 j f i 1 j 1 max next i j 1,0 開始忘...
BZOJ 3622 已經沒有什麼好害怕的了
這名字起的。題意 給出兩數列a,b都有n個元素,元素兩兩互不相同,問有多少種方案使得恰好 a i b j 的數目 a i b j 的數目 k?轉化 恰好有a i b j 的數目 n k 2 如果n k為奇數無解。link here 蒟蒻連普通dp也想不到啊otz 首先將糖果藥片們排序 設糖果i大於的...
BZOJ3622 已經沒有什麼好害怕的了
已經使 modoka 有簽訂契約,和自己一起戰鬥的想法後 mami 忽然感到自己不再是孤單一人了呢.於是,之前的謹慎的戰鬥作風也消失了 在對 charlotte 的傀儡使用終曲 tiro finale後 mami 面臨著即將被 charlotte 的本體吃掉的局面.這時,已經多次面對過 charlo...