这道题挺有意思的,和HDU5047 - Sawtooth[找规律]的类型是一样的,关键问题在于你要知道如何分割使得区域个数最多以及求出递推公式或直接公式。
题目链接:点这儿。
我们先来看一张图,看看如何叠加正方形使得分隔的区域数最多。
这么叠加会生成最多的分隔区域,具体分析可以参考HDU5047 - Sawtooth[找规律]。
因此可以得到递推式: 。
由于这个题的数据量不大,因此可以打表输出就行。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10001;
int f[maxn];
void init()
{
f[1] = 2;
for (int i = 2; i < maxn; ++i)
f[i] = f[i - 1] + 8 * (i - 1);
}
int main()
{
init();
int T;
scanf("%d", &T);
for (int n; T--; ) {
scanf("%d", &n);
printf("%d\n", f[n]);
}
return 0;
}
或者利用迭代(同样参见HDU5047 - Sawtooth[找规律])求出最终公式: 。
其实我一开始没有想到迭代这一做法,我的最直接想法竟然是矩阵快速幂,因此这里我把我一开始的做法分享一下。
这个公式 可以得到一个矩阵等式
具体详情可以参加博文深入浅出矩阵快速幂及其简单应用。
现在的问题就变成了
令
则
所以
即 。
我一开始就是这么做的!也好,给自己开阔了一个新的求通项公式的路子,也复习了线性代数。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d", &T);
for (int n; T--; ) {
scanf("%d", &n);
printf("%d\n", 2 + 4 * n * (n - 1));
}
return 0;
}