版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/V5ZSQ/article/details/82949051
Description
黑妹在玩游戏时又遇到了一个难题,这个游戏初始时给你 个整数 ,黑妹需要构建一个长度为 的数组使得该数组恰好包含这 个整数,剩下的位置将由黑妹填上一些不大于 的正整数,要求数组里任意相邻的两个整数互素。 黑妹轻松解决了这个游戏,但是她想知道具体有多少种方法构建这个数组。
由于答案可能很大,输出这个数对 取模后的值。
Input
第一行三个整数
Output
输出答案对 取模后的值。
Sample Input
3 8 2
Sample Output
50
Solution
以
表示放好前
个数字,已经用了
个
且第
个数字是
的方案数,枚举第
个数
,使得
,进而有转移
即为答案
Code
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
#define maxn 105
#define mod 1000000007
int add(int x,int y)
{
x+=y;
if(x>=mod)x-=mod;
return x;
}
int T,n,m,x,dp[maxn][maxn][maxn],gcd[maxn][maxn];
int main()
{
scanf("%d%d%d",&n,&x,&m);
for(int i=1;i<=100;i++)gcd[0][i]=gcd[i][0]=i;
for(int i=1;i<=100;i++)
for(int j=1;j<=i;j++)
gcd[i][j]=gcd[j][i]=gcd[j][i%j];
dp[0][0][1]=1;
for(int i=0;i<n;i++)
for(int j=0;j<=m;j++)
for(int k=1;k<=100;k++)
if(dp[i][j][k])
for(int l=1;l<=100;l++)
if(gcd[k][l]==1)
{
if(l!=x)dp[i+1][j][l]=add(dp[i+1][j][l],dp[i][j][k]);
else if(j<m)dp[i+1][j+1][l]=add(dp[i+1][j+1][l],dp[i][j][k]);
}
int ans=0;
for(int i=1;i<=100;i++)ans=add(ans,dp[n][m][i]);
printf("%d\n",ans);
return 0;
}