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 }

 

posted @ 2021-08-04 12:36  Rekord  阅读(1497)  评论(0编辑  收藏  举报