大致题意:
假如有一个数列a1,a2,a3,a4,a5....an。
如果对于每一个a[k],都有a[k+1]%a[k]==0.
那我们称这个数列为happy sequence。
现在给你两个数n和m,在保证每个happy sequence中的元素不大于n的情况下,求长度为m的happy sequence有多少个??
这道题用动态规划去做,首先找状态,我们设数组f[i][j]表示以i结尾且长度为j的happy sequence个数。
那么状态方程则为:
f[i][j]=sum(f[k][j-1]),k为i的所有因子
解释一下状态方程:
既然f[i][j]表示以i结尾且长度为j的happy sequence个数,那么在此类数列后面再加个i的倍数(i*k%i==0)也是一个happy sequence,所以以i结尾的长度为j的happy sequence个数为所有的以i的因子结尾的长度为j-1的happy sequence个数之和。
这道题还有一个注意点,也是我提交了7次还超时的原因,一直怀疑自己的方法是否错了、、、、、
题目里说n,m不大于2000,那我们预先都处理好了存在f数组里,以后就可以直接输出答案,不用一次一次的算了。。。。(我好笨)
代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
const int mod=1000000007;
int f[2005][2005];
vector<int>V[2005];
void init()
{
memset(f,0,sizeof(f));
for(int i=1; i<=2005; i++)V[i].clear();
for(int i=1; i<=2005; i++)
{
for(int j=1; j<=2005; j++)
{
if(j%i==0)
{
V[j].push_back(i);
}
}
}
for(int i=1; i<=2005; i++)f[i][1]=1;
for(int i=2; i<=2000; i++)
{
for(int j=1; j<=2000; j++)
{
for(int k=0; k<V[j].size(); k++)
{
f[j][i]=(f[j][i]%mod+f[V[j][k]][i-1]%mod)%mod;
}
f[j][i]%=mod;
}
}
}
int main()
{
int t;
init();//直接一次性都算出
while(~scanf("%d",&t))
{
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
int sum=0;
for(int i=1; i<=n; i++)
{
sum=(sum+f[i][m])%mod;//将所有以不大于n的数结尾且长度为m的happy sequence个数加起来就是答案了
}
printf("%d\n",sum);
}
}
}