10343 劃分凸多邊形(找規律,遞迴&分治,備忘)
阿新 • • 發佈:2019-01-29
10343 劃分凸多邊形
時間限制:800MS 記憶體限制:65535K
提交次數:0 通過次數:0
題型: 程式設計題 語言: C++;C;VC;JAVA
Description
問題描述:一個正凸N邊形,可以用N-3條互不相交的對角線將正N邊形分成N-2個三角形。 現在要求讀入N邊形的N(N≤20),輸出不同劃分方法的總數(要求解的是劃分方法數,而不需要輸出各種劃分法)。 這裡,注意: (1)頂點編號,認為頂點皆不相同,因此不允許認為將凸N邊形轉置視為相同劃分。 (2)若輸出是“No answer”,請注意大小寫和無標點。 輸入輸出舉例: 輸入: N=3, 輸出:1 輸入: N=5, 輸出:5 輸入: N=2, 輸出:No answer 輸入: N=6, 輸出:14 輸入: N=8, 輸出:132 例如: 當N=5時,共有5種分法。
輸入格式
N,代表正凸N邊形。
輸出格式
不同劃分方法的總數。
輸入樣例
5
輸出樣例
5
提示
題目所求的是分法總數,並不要求具體的分法。而且,N可以大到21。 因此,用簡單搜尋或列舉會耗時較多,而應該想方設法找出N為不同值時,分法總數的變化規律。 把一個正凸N邊形的各個頂點按照順時針分別編上1,2,……,N。 頂點1,頂點N和頂點I(I∈[2, N-1])能夠構成一個三角形S。 這樣凸N邊形就被分成三部分:一個三角形S、一個I邊形和一個N+1-I邊形(I, N+1-I∈[2, N-1])。 因此,凸N邊形分為三角形總數Total(N)等於I邊形的分法總數乘以N+1-I邊形的分法總數之積,還要在I分別取2,3,……,N-1時都累加起來。 遞推公式如下: Total(N) = sum{ Total(I)*Total(N+1-I) | for I=2 to N-1} if N>=4 Total(2) = Total(3) = 1 注意: 2點的多邊形視為蛻化的多邊形,定義其Total(2)=1,是為遞推公式推導用。 但按題目意思當N=2時輸出無解。 另外,此題需要注意的是,如果你寫的純遞迴程式可能會超時的,因為這裡遞迴存在重複,且重複數量龐大。 需要用陣列將你算過的元素儲存下來,避免重複的遞迴計算,這樣優化後,才能通過。
作者
zhengchan
我的實現程式碼
#include <iostream> #include <cmath> #include <string.h> using namespace std; int *arr; int Total(int n){ if (arr[n] != 0) {//有備忘記錄 return arr[n]; } int count = 0; for (int i = 2; i < n; i++) { count += Total(i) * Total(n + 1 -i); } arr[n] = count;//進行到此,記錄此備忘 return count; } int main() { int n; cin >> n; if (n == 2) {//預處理 cout << "No answer"; }else{ arr = new int[n + 1]; memset(arr, 0, (n + 1) * sizeof(int)); arr[2] = 1; arr[3] = 1; cout << Total(n); } cout << endl; return 0; }