zoj-4011(动态规划)
Posted kasenbob
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了zoj-4011(动态规划)相关的知识,希望对你有一定的参考价值。
本题的动态规划公式是f[i][j]=f[i][j]+f[k][j-1],表示以i结尾的长度为j的序列,k为i的因子;
不难发现,计算中存在一个状态叠加的过程,即任意一个i都是它的因子的所有情况的叠加,例如[9][3],它会是以1,3结尾的长度为2的状态的叠加;
代码如下:
#include<iostream> #include<cstring> #include<string> #include<algorithm> #include<map> #include<vector> #include<cstdio> #include<cmath> using namespace std; const int maxn=2000+10; const int mod=1e9+7; int flag[maxn][maxn];/*状态转移方程*/ vector<int>v[maxn];/*用来存放v[i]的所有因子*/ void csh() { memset(flag,0,sizeof(flag)); for(int i=1;i<maxn;i++) { for(int j=1;j<maxn;j++) { if(j%i==0) v[j].push_back(i);/*存放因子*/ } } for(int i=1;i<maxn;i++) { flag[i][1]=1;/*初始状态即以i结尾长度为1的情况都只有一种*/ } for(int i=2;i<maxn;i++) { for(int j=1;j<maxn;j++) { for(int k=0;k<v[j].size();k++) { flag[j][i]=flag[j][i]%mod+flag[v[j][k]][i-1]%mod;/*状态叠加*/ } flag[i][j]%=mod; } } } int main() { csh(); int t; while(scanf("%d",&t)!=EOF) { while(t--) { int n,m; scanf("%d %d",&n,&m); long long sum=0; for(int i=1;i<=n;i++) { sum=(sum+flag[i][m])%mod; } printf("%lld ",sum); } } }
以上是关于zoj-4011(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章