zoukankan      html  css  js  c++  java
  • poj3718 Facer's Chocolate Dream

    题目戳这里

    这是一道好题。首先我们将模型转换一下,就两个01串异或一下,得到新串(S)。现在就是求有有多少种选法,从空集合变成(S)。其实这到题目只跟(S)(1)的数目有关——因为所有巧克力是等价的。我们设(f[m][T])表示前(m)次操作,使得集合中有(T)(1)的方案数。转移:

    [f[a][b] = left( sum_{i=0}^3f[a-1][b+2i-3] imes inom{N-b}{i} imes inom{b}{3-i}-f[a-2][b] imes left(inom{N}{3}-a+2 ight) ight)/a ]

    我们现在来解释一下这个方程。

    [sum_{i=0}^3f[a-1][b+2i-3] imes inom{N-b}{i} imes inom{b}{3-i} ]

    我们枚举我们接下拿的那盘用(i)盘是从(0)变成(1)(3-i)盘是从(1)变成(0)(不管重复)。这里可能有人问为什么是(inom{N-b}{i})不是什么xxx(具体的我忘了)的。因为如果那样你就把(1)的位置也考虑进来了,这样是把(1)的位置固定了。

    然后就是把重复的部分减去。我们不妨设第(a)次与(a-1)次重复了(反正是组合),我们就可以减去$$f[a-2][b] imes inom{N}{3}-a+2$$

    然后这一次可以发生在前(a)次中任何一次,故最后除以个(a)(因为我们在这里强加了次序,我们把它当作了排列,实际为组合)。

    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    const int maxn = 1010,rhl = 10007;
    int N,M,cnt,C[maxn][maxn],f[maxn][maxn],inv[maxn]; bool A[maxn],exist[maxn][maxn];
    
    inline int qsm(int a,int b)
    {
    	int ret = 1;
    	for (;b;b >>= 1,(a *= a) %= rhl) if (b & 1) (ret *= a) %= rhl;
    	return ret;
    }
    inline void ready()
    {
    	for (int i = 1;i <= 1000;++i) inv[i] = qsm(i,rhl-2);
    	C[0][0] = 1;
    	for (int i = 1;i <= 1000;++i)
    	{
    		C[i][0] = 1;
    		for (int j = 1;j <= i;++j)
    		{
    			C[i][j] = C[i-1][j-1]+C[i-1][j];
    			if (C[i][j] >= rhl) C[i][j] -= rhl;
    		}
    	}
    }
    
    inline int dp(int a,int b)
    {
    	if (exist[a][b]) return f[a][b];
    	if (a == 0) return 0;
    	exist[a][b] = true;
    	for (int i = 0;i <= 3;++i)
    	{
    		if (N-b < i||3-i > b) continue;
    		f[a][b] += dp(a-1,b+2*i-3)*C[N-b][i]%rhl*C[b][3-i]%rhl;
    		if (f[a][b] >= rhl) f[a][b] -= rhl;
    	}
    	f[a][b] -= f[a-2][b]*(C[N][3]-a+2)%rhl;
    	if (f[a][b] < 0) f[a][b] += rhl;
    	if (f[a][b] >= rhl) f[a][b] -= rhl;
    	(f[a][b] *= inv[a]) %= rhl;
    	return f[a][b];
    }
    
    int main()
    {
    	freopen("3718.in","r",stdin);
    	freopen("3718.out","w",stdout);
    	ready();
    	while (true)
    	{
    		scanf("%d %d",&N,&M); if (!N && !M) break; cnt = 0;
    		for (int i = 1,a;i <= N;++i) scanf("%1d",&a),A[i] = (bool)a;
    		for (int i = 1,a;i <= N;++i) scanf("%1d",&a),cnt += (a^(int)A[i]);
    		for (int i = 0;i <= M;++i) for (int j = 0;j <= N;++j) f[i][j] = exist[i][j] = 0;
    		f[0][0] = 1; exist[0][0] = true;
    		printf("%d
    ",dp(M,cnt));
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    Composite in Javascript
    Model Validation in Asp.net MVC
    HttpRuntime.Cache vs. HttpContext.Current.Cache
    Controller Extensibility in ASP.NET MVC
    The Decorator Pattern in Javascript
    The Flyweight Pattern in Javascript
    Model Binding in ASP.NET MVC
    Asp.net MVC
    jQuery Ajax 实例 全解析
    ASP.NET AJAX入门系列
  • 原文地址:https://www.cnblogs.com/mmlz/p/6388438.html
Copyright © 2011-2022 走看看