时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
Given two positive integers N and M, please divide N into several integers A1, A2, …, Ak (k >= 1), so that:
0 < A1 < A2 < … < Ak;
A1 + A2 + … + Ak = N;
A1, A2, …, Ak are different with each other;
The product of them P = A1 * A2 * … * Ak is a multiple of M;
How many different ways can you achieve this goal?
输入
Two integers N and M. 1 <= N <= 100, 1 <= M <= 50.
输出
Output one integer – the number of different ways to achieve this goal, module 1,000,000,007.
样例提示
There are 4 different ways to achieve this goal for the sample:
A1=1, A2=2, A3=4;
A1=1, A2=6;
A1=2, A2=5;
A1=3, A2=4.
样例输入
7 2
样例输出
4
#include "iostream"
#include "fstream"
#include "string.h"
using namespace std;
int N, M;
int f[101][101][51];
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a%b);
}
int dfs(int last, int sum, int GCD)
{
if(f[last][sum][GCD] != -1)
{
return f[last][sum][GCD];
}
else
{
if(sum == N)
{
if(GCD == M)
return f[last][sum][GCD] = 1;
else
return f[last][sum][GCD] = 0;
}
else
{
int cnt = 0;
for(int i=last+1; i<=N-sum; i++)
{
cnt += dfs(i, sum+i, gcd(GCD*i, M));
cnt %= 1000000007;
}
return f[last][sum][GCD] = cnt;
}
}
}
int main()
{
//ifstream cin;
//cin.open("1.txt");
cin >> N >> M;
memset(f, -1, sizeof(f));
cout << dfs(0, 0, 1);
return 0;
}