sgu 130

本文探讨了一个关于圆上点的分割方案数问题,通过递归和记忆化解决,提供了完整的代码实现和详细解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

画个图,就很好想了
假设圆上有n = 2 * k个点.选定一个点为点1,然后顺时针给其他点编号2,3...n
考虑一下点1应该和哪些点相连,画个图,可以看出,有可能与点1相连的点为2,4,6...n
进一步,假设点1与点p相连了, 那么我们将园分割成了两部分,这两部分包含的点分别为:
2,3,4,5,6,...,p - 1 和 p+1, p+2,....,n
这两部分,可以进一步做分割, 这样子,我们就成功把原问题转化为子问题了, 可以递归解决了.
最后, 为了不TLE, 需要做记忆化的处理。

#include <cstdio>
#include <vector>
#include <cmath>
#include <cassert>
using namespace std;

typedef __int64 int64;

vector<int64> f;

//圆上有n个点, 返回不同的分割方案数
int64 solve(int n) {
    if (n == 0) return 1;
    if (n == 2) return 1;
    if (n == 4) return 2;
    if (f[n / 2] != -1) return f[n / 2];

    int i;
    int64 ans = 0;
    for (i = 2; i <= n; i += 2) {
        ans = ans + solve(i - 2) * solve(n - i);
    }
    return f[n/2] = ans;
}


int main() {
    int k;
    int i;
    scanf("%d", &k);
    f.resize(k + 2);
    for (i = 0; i < f.size(); ++i) f[i] = -1;

    for (i = 6; i <= 2 * k; i += 2) {
        solve(i);
    }
    printf("%I64d %d\n", solve(2 * k), k + 1);
    return 0;
}


转载于:https://my.oschina.net/mustang/blog/55678

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值