学习C++从娃娃抓起!记录下在学而思小猴编程学习过程中的题目,记录每一个瞬间。侵权即删,谢谢支持!
附上汇总贴:小猴编程C++ | 汇总-CSDN博客
【题目描述】
有一个数列
a
1
,
a
2
,
…
,
a
n
a_1,a_2,\dots,a_n
a1,a2,…,an,现在要从其中取若干个数,从小到大排序后,要求后一个数是前一个数的倍数。
假设取出了
k
k
k个数
(
1
≤
k
≤
n
)
(1\le k\le n)
(1≤k≤n),从小到大排序后是
b
1
,
b
2
,
…
,
b
k
b_1,b_2,\dots,b_k
b1,b2,…,bk。我们要求这些数满足如下条件:对
i
=
2
,
3
,
…
,
k
i=2,3,\dots,k
i=2,3,…,k,
b
i
b_i
bi是
b
i
−
1
b_{i-1}
bi−1的倍数。满足这个条件的序列
b
b
b称作倍数序列。(只有1个数也算是倍数序列)
问有多少种不同的倍数序列?
【输入】
第1行,1个正整数
n
n
n
第2行,
n
n
n个正整数
a
1
,
a
2
,
…
,
a
n
a_1,a_2,\dots,a_n
a1,a2,…,an
【输出】
输出不同的倍数序列个数。
【输入样例】
5
3 12 4 1 20
【输出样例】
15
【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 5005;
int n;
long long ans, a[N], f[N];
int main()
{
scanf("%d", &n);
for (int i=1; i<=n; i++) { // 数据范围超long long,所以用scanf输入,类型为%lld
scanf("%lld", &a[i]);
}
sort(a+1, a+n+1); // 按照从小到大排序
for (int i=1; i<=n; i++) {
f[i] = 1; // 每个i都可以以自己为开头且结尾(即自己成为一个序列),所以初值赋值为1
for (int j=1; j<i; j++) { // 因为已经排过序,所以只需枚举小于i
if (a[i]%a[j]==0) { // 如果a[j]是a[i]的约数
f[i] += f[j]; // 那么i的方案数就再加上j的方案数
}
}
ans += f[i]; // 将i的方案数加到总和中
}
printf("%lld\n", ans); // 打印所有数作为序列尾部的方案数
return 0;
}
【运行结果】
5
3 12 4 1 20
15