HDU 2050——折線分割平面【遞推】

題目傳送門

Problem Description

我們看到過很多直線分割平面的題目,今天的這個題目稍微有些變化,我們要求的是n條折線分割平面的最大數目。比如,一條折線可以將平面分成兩部分,兩條折線最多可以將平面分成7部分,具體如下所示。
在這裏插入圖片描述

Input

輸入數據的第一行是一個整數C,表示測試實例的個數,然後是C 行數據,每行包含一個整數n(0<n<=10000),表示折線的數量。

Output

對於每個測試實例,請輸出平面的最大分割數,每個實例的輸出佔一行。

Sample Input

2
1 2

Sample Output

2
7

分析:

交點決定了射線和線段的條數,進而決定了新增的區域數。當n-1條折線時,區域數爲f(n-1)。爲了使增加的區域最多,則折線的兩邊的線段要和n-1條折線的邊,即2*(n-1)條線段相交。那麼新增的線段數爲4*(n-1)射線數爲2。但要注意的是,折線本身相鄰的兩線段只能增加一個區域。

故:
f(n) = f(n-1) + 4(n-1) + 2 - 1【記憶化+打表即可】

【繼續優化可得到線性答案】
= f(n-1) + 4(n-1) + 1
= f(n-2) + 4(n-2) + 4(n-1) + 2
……
= f(1) + 4 + 4*2 + …… + 4(n-1) + (n-1)
= 2n2 - n + 1

AC代碼:

#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <set>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;

#define INF 0X3F3F3F


ll ans[10005];
ll f(ll x) {
    if (ans[x] == 0)
        return ans[x] = 2 * f(x - 1) + 1;
    else
        return ans[x];
}
int main() {
    ans[1] = 2;
    ans[2] = 7;
    for (int i = 2; i <= 10001; i++)
    {
        ans[i] = ans[i - 1] + 4 * i - 3;
    }
    int T;
    while (cin >> T) {
        while (T--) {
            ll n;
            cin >> n;
            cout << ans[n] << endl;
        }
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章