洛谷P1028数的计算

https://www.luogu.org/problemnew/show/P1028

只用递归会超时,需要用递归型动规,用一个数组保存已经算过的值,避免重复计算。

求数字为n的方案数的最优子结构为:求数字从1到n/2的方案数之和再加上这个数字本身,即fn=f1+f2+...+f(n/2)+1,

边界为:1的符合条件的方案数只有它自己,即f1=1.

例:

f(6)=f(1)+f(2)+f(3)+1=1+2+2+1=6.

f1=1,f2=f1+1=1+1=2,f3=f1+1=1+1=2。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 //int cnt = 1;
 5 int dp[1010];
 6 int f(int n)//数字为n的方案数
 7 {
 8     if (n == 1)//1满足条件的只有它自己
 9     {
10         dp[n] = 1;
11         return dp[n];
12     }
13     if (dp[n] != 0)
14     {
15         return dp[n];
16     }
17     int e = n / 2;
18     int sum = 0;
19     for (int i = 1; i <= e; ++i)
20     {
21         sum += f(i);
22     }
23     dp[n] = sum + 1;//不为1的方案数除了从1到n/2的方案数之和还得加上这个数字自己
24     return dp[n];
25 }
26 int main()
27 {
28     int n;
29     memset(dp, 0, sizeof(dp));
30     cin >> n;
31     
32     cout << f(n)<< endl;
33     return 0;
34 }    

 

posted @ 2018-09-05 10:45  敲代码不BB  阅读(177)  评论(0编辑  收藏  举报