ACM训练 训练方式 [简单递归+记忆化搜索]

  • 题目
  • 题目分析
  • 整体代码

题目

题目描述

自行车选手在训练时,需要围绕着场地骑行N圈。给了使得训练有效,可以一次把N全部骑完,
也可以分成若干次完成,但每次都比上一次骑的圈数要多,那么完成一次训练即骑完N圈,有多种训练方式

样例输入

6

样例输出

4

题目分析

例如,当 N = 6 时,有以下四种训练方案:
6
1 2 3
1 5
2 4

细细想来,这就是一个简单的递归,每次传递的参数是上一个已选值(这次选的不能比这个值小了)和当前剩余可用总量
若是不使用记忆化搜索,数据到100往上就比较吃力了,因此显然需要使用记忆化搜索。

整体代码

#include
#include
#include
#define maxn 500
using namespace std;
long long m[maxn][maxn];
bool vis[maxn][maxn];
int dd(int i, int n) {
    if (vis[i][n])
        return m[i][n];
    vis[i][n] = true;
    if (n == 0)
        return m[i][n] = 1;
    else if (i >= n)
        return m[i][n] = 0;
    else {
        for (int j = i + 1; j <= n; ++j) {
            m[i][n] += dd(j, n - j);
        }
        return m[i][n];
    }
}
int main() {
    int n;
    while (cin >> n) {
        memset(m, 0, sizeof(m));
        memset(vis, false, sizeof(vis));
        for (int i = 1; i <= n; ++i) {
            dd(i, n - i);
        }
        for (int i = 1; i <= n; ++i)
                m[0][n] += m[i][n-i];
        cout << m[0][n] << endl;
    }
}

你可能感兴趣的:(NUIST,OJ)