1316:【例4.6】数的计数(Noip2001)
看到题目,我们很容易就会写出类似于下面这样的代码。
然后最后一个测试集过不去……(ε=(´ο`*)))唉)
1 #include<iostream> 2 using namespace std; 3 4 int ans; 5 void cnt(int ori){ 6 ans++; 7 for(int i=1;i<=ori/2;i++) 8 cnt(i); 9 } 10 int main(){ 11 int n; 12 cin>>n; 13 cnt(n); 14 cout<<ans; 15 return 0; 16 }
显然,程序做了许多重复性操作。
比如给定原数12,那么理论上212以后满足条件的数量等于2612以后满足条件的数量。
对于每个原数其实是可以复用的。
所以,是不是动态规划的味道越来越浓了?罒ω罒
然后,我的代码就变成了下面这样的动态规划(*^▽^*)!
1 #include<iostream> 2 using namespace std; 3 4 const int N=505; 5 int ans,mem[N]; 6 void cnt(int ori){ 7 //初始化 8 mem[0]=1; 9 for(int i=1;i<=ori/2;i++){ 10 for(int j=0;j<=i/2;j++){ 11 mem[i]+=mem[j]; 12 } 13 ans+=mem[i]; 14 } 15 } 16 int main(){ 17 int n; 18 cin>>n; 19 cnt(n); 20 cout<<ans+1; 21 return 0; 22 }
再提供一种大佬的解法。(转载自https://blog.csdn.net/Wchenchen0/article/details/81063739)
正经的递归
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 const int N=1005; 6 int mem[N]; 7 void cnt(int ori){ 8 if(mem[ori]>0)return; 9 mem[ori]=1;//本身有一种情况 10 for(int i=1;i<=ori/2;i++){ 11 cnt(i); 12 mem[ori]+=mem[i]; 13 } 14 } 15 int main(){ 16 int n; 17 cin>>n; 18 memset(mem,0,sizeof(0)); 19 cnt(n); 20 cout<<mem[n]; 21 return 0; 22 }