题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1723
方法:
根据题意,设st为传递消息开始的人,ed是接收消息的最后一个人,m为每个最多可以向后传达的人数(距离),F(st,ed)为从st到ed传递消息的方式个数,建立如下状态转移方程:
{
F(st,ed) = 1 ,st==ed;
0 ,st>ed;
sum(F(st+i,ed)|1<=i<=m);
}
F(1,n)为原问题的解。
感谢:通过做记录集避免重复计算,来优化递归的性能。
代码:
#include<iostream> //#include<math.h> #include<algorithm> using namespace std; int records[32][32]; int t_records[32][32]; int getResult(int s,int e, int t) { if(records[s][e]!=-1) return records[s][e]; if(s==e) return 1; else if(s>e) return 0; else { int sum = 0; for(int i=1;i<=t;i++) sum+=getResult(s+i,e,t); records[s][e]=sum; return sum; } } int main() { int n,m; for(int i=0;i<=30;i++) for(int j =0;j<i;j++) { memset(records,-1,sizeof(records)); t_records[i][j] = getResult(1,i,j); } while(scanf("%d %d",&n,&m) && n+m!=0) cout<<t_records[n][m]<<endl; return 0; }