旅行 数论 打表找规律

传送门
题意:

转眼毕业了,曾经朝夕相处的同学们不得不都各奔东西,大家都去了不同的城市开始新的生活。在各自城市居住了一段时间后,他们都感到了一些厌倦,想去看看其他人的生活究竟如何,于是他们都选择到另一个同学所在城市去旅游,并且希望旅游的城市各不相同,他们想知道有多少种不同的方案,可是数量实在太多了,他们无法计算出来,你能帮助他们吗。

看到题目先打个暴力吧
233

#include <cstdio>
#include <cstring>
#include <algorithm>

int n;
int a[10000];
bool vis[10000];
int ans = 0;


void dfs(int x) {
    if (x == n + 1) {
        ans++;
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (i == x || vis[i]) continue;
        a[x] = i;
        vis[i] = 1;
        dfs(x + 1);
        a[x] = 0;
        vis[i] = 0;
    }
}
int main () {
    scanf("%d", &n);
    dfs(1);
    printf("%d", ans);
    return 0;
}

好像有点感觉了?。。。打个表出来看看

2 - 1
3 - 2
4 - 9
5 - 44
6 - 265

好像有点关系,,
分析一下,,,

ans[n]=(ans[n1]+ans[n2])(n1)

好像没什么问题吧,,,
开始写,,,
233

咦好像需要高精度

233

手抖把高精度打错了,,,高精乘单精应该在最后再进位,,高精加法把+=打成=。。用哪个遇到重载运算符就崩的gdb调了老久才发现,,

好吧AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>


struct bigint{
    int num;
    int a[10000];
    void clr(void) {
        memset(a, 0, sizeof(a));
    }
    void print(void) {
        for (int i = num; i >= 1; i--) printf("%d", a[i]);
    }
};

int n;
bigint ans[210];

bigint operator * (bigint xx, int p) {
    for (int i = 1; i <= xx.num; i++) {
        xx.a[i] *= p;
    }
    for (int i = 1; i <= xx.num; i++) {
        if (xx.a[i] > 10) {
            xx.a[i+1] += xx.a[i] / 10;
            xx.a[i] %= 10;
        }
    }
    if (xx.a[xx.num+1] == 0) return (xx);
    xx.num++;
    while (xx.a[xx.num] > 10) {
        xx.a[xx.num+1] += xx.a[xx.num] / 10;
        xx.a[xx.num] %= 10;
        xx.num++;
    }
    return (xx);
}

bigint operator + (bigint aa, bigint bb) {
    bigint cc;
    cc.clr();
    cc.num = std :: max(aa.num, bb.num);
    for (int i = 1; i <= cc.num; i++) {
        cc.a[i] += aa.a[i] + bb.a[i];
        if (cc.a[i] > 10) {
            cc.a[i+1] += cc.a[i] / 10;
            cc.a[i] = cc.a[i] % 10; 
        }
    }
    if (cc.a[cc.num+1] == 0) return (cc);
    cc.num++;
    while (cc.a[cc.num] > 10) {
        cc.a[cc.num + 1] += cc.a[cc.num] / 10;
        cc.a[cc.num] = cc.a[cc.num] % 10;
        cc.num++;
    }
    return (cc);
}

int main () {
    scanf("%d", &n);
    ans[2].a[1] = 1;
    ans[2].num = 1;
    ans[3].a[1] = 2;
    ans[3].num = 1;
    for (int i = 4; i <= n; i++) {
        ans[i] = (ans[i-1] + ans[i-2]) * (i-1);
    }
    ans[n].print();


    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值