zoukankan      html  css  js  c++  java
  • 【NOIP2012模拟10.26】电影票

    本题规律难找:
    我们可以这么想:
    我们先求出所有的方案,然后在去掉不正确的方案即可。
    所有的方案:C(n,n+m)
    不正确的方案:C(m-1,(n+1)+(m-1))=C(m-1,n+m)
    于是答案便为:

    C(n,n+m)- C(m-1,n+m)

    我们化简化简(#^ . ^#)

    =(n+m)!/n!/m!-(n+m)!/(m-1)!/(n+1)!
    =(n+m)!(n+1)/(n+1)!/m!-(n+m)!*m/m!/(n+1)!
    =(n+m)!*(n-m+1)/(n+1)!/m!
    =(n+2)x…x(n+m)*(n-m+1)/m!

    这样我想时间复杂度应当是大大减小了。
    然后压压位,这样便肯定不会时超了!

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define mo 100000000000000
    using namespace std;
    struct node {int len; ll a[2010];}ans,c;
    int n,m;
    
    node cheng(node a,ll y)
    {
    	c.len=a.len+2;
    	ll x=0;
    	for (int i=1;i<=c.len;i++)
    	{
    		c.a[i]=a.a[i]*y+x;
    		x=c.a[i]/mo,c.a[i]%=mo;
    	}
    	while (!c.a[c.len]) c.len--;
    	return c;
    }
    
    node divide(node a,ll y)
    {
    	c.len=a.len;
    	ll x=0,h;
    	for (int i=c.len;i>0;i--)
    	{
    		h=(a.a[i]+x)%y;
    		c.a[i]=(a.a[i]+x)/y;
    		x=h*mo;
    	}
    	while (!c.a[c.len]) c.len--;
    	return c;
    }
    
    int main()
    {
    	freopen("movie.in","r",stdin);
    //	freopen("movie.out","w",stdout);
    	scanf("%d%d",&n,&m);
    //	 C(n,n+m)-C(m-1,n+m)
    //	=(n+m)!/m!/n!-(n+m)!/(m-1)!/(n+1)!
    //	=(n+2)*...*(n+m)*(n-m+1)/m!
    	ans.a[1]=n-m+1;ans.len=1;
    	for (int i=n+2;i<=n+m;i++)
    		ans=cheng(ans,i);
    	for (int i=2;i<=m;i++)
    		ans=divide(ans,i);
    	printf("%lld",ans.a[ans.len]);
    	for (int i=ans.len-1;i>0;i--)
    		printf("%014lld",ans.a[i]);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    dp学习笔记1
    hdu 4474
    hdu 1158(很好的一道dp题)
    dp学习笔记3
    dp学习笔记2
    hdu 4520+hdu 4522+hdu 4524(3月24号Tencent)
    hdu 1025(最长非递减子序列的n*log(n)求法)
    hdu 2063+hdu 1083(最大匹配数)
    hdu 1023
    《 Elementary Methods in Number Theory 》Exercise 1.3.12
  • 原文地址:https://www.cnblogs.com/jz929/p/11817758.html
Copyright © 2011-2022 走看看