传送门
题意:
转眼毕业了,曾经朝夕相处的同学们不得不都各奔东西,大家都去了不同的城市开始新的生活。在各自城市居住了一段时间后,他们都感到了一些厌倦,想去看看其他人的生活究竟如何,于是他们都选择到另一个同学所在城市去旅游,并且希望旅游的城市各不相同,他们想知道有多少种不同的方案,可是数量实在太多了,他们无法计算出来,你能帮助他们吗。
看到题目先打个暴力吧
#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[n−1]+ans[n−2])∗(n−1)
好像没什么问题吧,,,
开始写,,,
咦好像需要高精度
手抖把高精度打错了,,,高精乘单精应该在最后再进位,,高精加法把+=打成=。。用哪个遇到重载运算符就崩的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;
}