http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1194
不看解析还真没有什么思路,刘汝佳的《算法竞赛入门经典训练指南》P117
将原问题转换成树 然后再进行树型DP
代码:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define ll long long using namespace std; const int N=100; ll dp[N][N]; ll C(ll n,ll m) { if(m==0||n<=1) return 1; double tmp=1.0; for(int i=0;i<m;++i) tmp=tmp*(n-i)/(i+1); return tmp+0.5; } ll dfs(int x,int y) { if(dp[x][y]!=-1) return dp[x][y]; if(y==1||x==1||x==0) return (dp[x][y]=1); dp[x][y]=0; for(int l=0;l*y<=x;++l) { dp[x][y]+=(dfs(x-y*l,y-1)*C(dfs(y,y-1)+l-1,l)); } return dp[x][y]; } int main() { //freopen("data.in","r",stdin); memset(dp,-1,sizeof(dp)); int n; while(cin>>n) { if(!n) break; if(n==1) cout<<"1"<<endl; else cout<<dfs(n,n-1)*2<<endl; } return 0; }