DP+数学  恶心死我了 DP那部分没什么 数学的那部分各种细节各种繁琐呀

在比赛中就可以做出来这种题的人果然不一般 自己还需锻炼呀

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<stack>
#include <iomanip>
using namespace std;
#define LL long long
const double eps=1e-6;
const int INF=0x3f3f3f3f;
const int N=52;
const int M=1501;
const long long MOD=1000000007;
long long sum[N][N][M];
long long b[N];
bool prime(int n)
{
    for(int i=2;i*i<=n;++i)
    if(n%i==0)
    return false;
    return true;
}
long long C(long long n,int m)
{
     int a[N],I=0;
     for(int i=2;i<=m;++i)
     if(prime(i))
     a[I++]=i;
     for(int i=1;i<=m;++i)
     b[i]=n-m+i;
     for(int i=2;i<=m;++i)
     {
         int k=i;
         for(int j=0;j<I&&k>1;++j)
         if(k%a[j]==0)
         {
             k=k/a[j];
             for(int l=1;l<=m;++l)
             if(b[l]%((long long)(a[j]))==0)
             {b[l]=b[l]/((long long)(a[j]));break;}
             --j;
         }
     }
     long long tmp=(long long)(1);
     for(int i=1;i<=m;++i)
     tmp=(tmp*(b[i]%MOD))%MOD;
     return tmp;
}
class DistinctRemainders
{
    public :
    int howMany(long long n, int m)
    {
        memset(sum,0,sizeof(sum));
        for(int i=0;i<=m;++i)
        sum[i][0][0]=(long long)(1);
        int a=0;
        for(int i=1;i<=m;++i)
        {
            for(int j=1;j<=i;++j)
            {
                for(int l=0;l<=a;++l)
                {
                    sum[i][j][l]=sum[i-1][j][l];
                    if(l-(i-1)>=0)
                    sum[i][j][l]=(sum[i][j][l]+sum[i-1][j-1][l-(i-1)])%MOD;
                }
            }
            a=a+i;
        }
        long long ans=0;
        long long lm=(long long)(m);
        for(int j=1;j<=m;++j)
        for(int l=(int)(n%lm);l<M&&((long long)(l)<=n);l+=m)
        {
            if(sum[m][j][l]>0)
            {
            	long long h=(n-(long long)(l))/lm;
            	if(h<0) continue;
                long long tmp=C(h+j-1,j-1);
                for(int w=1;w<=j;++w)
                tmp=(tmp*(long long)(w))%MOD;
                tmp=(tmp*sum[m][j][l])%MOD;
                ans=(ans+tmp)%MOD;
            }
        }
        return (int)(ans);
    }
};

  

posted on 2013-03-07 18:14  夜->  阅读(186)  评论(0编辑  收藏  举报