zoj3662Math Magic

Math Magic

Time Limit: 3 Seconds       Memory Limit: 32768 KB

Yesterday, my teacher taught us about math: +, -, *, /, GCD, LCM... As you know, LCM (Least common multiple) of two positive numbers can be solved easily because of a * b = GCD (a, b) * LCM (a, b).

In class, I raised a new idea: "how to calculate the LCM of K numbers". It's also an easy problem indeed, which only cost me 1 minute to solve it. I raised my hand and told teacher about my outstanding algorithm. Teacher just smiled and smiled...

After class, my teacher gave me a new problem and he wanted me solve it in 1 minute, too. If we know three parameters N, M, K, and two equations:

1. SUM (A1, A2, ..., Ai, Ai+1,..., AK) = N 
2. LCM (A1, A2, ..., Ai, Ai+1,..., AK) = M

Can you calculate how many kinds of solutions are there for Ai (Ai are all positive numbers). I began to roll cold sweat but teacher just smiled and smiled.

Can you solve this problem in 1 minute?

Input

There are multiple test cases.

Each test case contains three integers N, M, K. (1 ≤ N, M ≤ 1,000, 1 ≤ K ≤ 100)

Output

For each test case, output an integer indicating the number of solution modulo 1,000,000,007(1e9 + 7).

You can get more details in the sample and hint below.

Sample Input

4 2 2

3 2 2

Sample Output

1

2

Hint

The first test case: the only solution is (2, 2).

The second test case: the solution are (1, 2) and (2, 1).

这题时间卡的真紧啊!

 

#include <iostream>

#include <stdio.h>

#include <math.h>

#include <string.h>

using namespace std;

#define MAXN 1005

#define mod 1000000007

int lca[MAXN][MAXN],dp[2][MAXN][MAXN],vec[MAXN];

int gcd(int a,int b)

{

    if(a==0)return b;

    return gcd(b%a,a);

}

int main()

{

    int n,m,k,i,j,now,no,k1,j1,ans,ii;

    for(i=1;i<=1000;i++)

        for(j=i;j<=1000;j++)

            lca[j][i]=lca[i][j]=i/gcd(i,j)*j;

    while(scanf("%d%d%d",&n,&m,&no)!=EOF)

    {

        now=0;

        //memset(dp,0,sizeof(dp));

        ans=0;

        vec[ans++]=1;

        for(i=2;i<=m;i++)

        {

            if(m%i==0)

            vec[ans++]=i;

        }

        for(ii=0;ii<=n;ii++)

            for(j=0;j<ans;j++)

                dp[now][ii][vec[j]]=0;

            dp[now][0][1]=1;

        for(i=0;i<=no-1;i++)

        {

            now=now^1;

            for(ii=0;ii<=n;ii++)

                for(j=0;j<ans;j++)

                dp[now][ii][vec[j]]=0;

            for(j=i;j<=n;j++)

                for(int j2=0;j2<ans;j2++)

                {

                    k=vec[j2];

                    if(dp[now^1][j][k]==0)

                    continue;

                      for(int jj1=0;jj1<ans;jj1++)

                    {



                        j1=vec[jj1];

                        if(j1+j>n)

                        break;

                        k1=lca[k][j1];

                       if(k1>m||m%k1!=0)

                        continue;

                        dp[now][j1+j][k1]+=dp[now^1][j][k];



                        dp[now][j1+j][k1]%=mod;

                    }

                }



        }

        printf("%d\n",dp[now][n][m]%mod);

    }

    return 0;

}


 

 

你可能感兴趣的:(Math)