Problem Description
我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目。比如,一条折线可以将平面分成两部分,两条折线最多可以将平面分成7部分,具体如下所示。
Input
输入数据的第一行是一个整数C,表示测试实例的个数,然后是C 行数据,每行包含一个整数n(0<n<=10000),表示折线的数量。
Output
对于每个测试实例,请输出平面的最大分割数,每个实例的输出占一行。
Sample Input
3
1
2
3
Sample Output
2
7
16
分析:
先看简单情况:用n条直线划分平面,且第n条直线必须与之前的直线相交
一条直线,将平面分成两部分
两条直线将平面分成4部分: 第二条红线与第一条直线相交一点,交1点,产生两条线段,而两条线段将之前的1,2部分又分为了两部分,所以一共产生了4个部分。
三条直线,第三条直线与前两条相交,交于2点,产生了3条线段,而三条线段将三块区域分别划分成了两块区域,共六块区域,共增加3块区域,所以一共产生了4 + 3 = 7块区域
所以这种情况的状态转移方程为f(n) = f(n - 1) + (n - 1) + 1;
f(n - 1): 之前的区域数量
n - 1: 交点个数, 交点个数为第n条线之前的直线个数
(n - 1) + 1: 交点个数 + 1 = 线段数
线段数可以把线段所在的区域都分为两块,区域数量分别增加一块,所以一共增加(n - 1) + 1块。
以此类推:
n条折线,前n - 1条折线共2(n - 1)条直线,而第n条折线由两条线组成,每条分别与前2(n-1)条直线交出2(n-1)个点, 所以共4(n-1)个点,共4(n-1)+1条线段。
所以对应的状态转移方程为: f(n) = f(n - 1) + 4(n - 1) + 1;
#include<bits/stdc++.h>
using namespace std;
long long dp[10005] = {0, 2, 7};
int n, c;
int main() {
scanf("%d", &c);
for(int i = 2; i <= 10000; i++) {
dp[i] = dp[i - 1] + 4 * (i - 1) + 1;
}
while(c--) {
scanf("%d", &n);
printf("%lld\n", dp[n]);
}
return 0;
}