Problem Summary

Take all lattice points on the boundary of an \(N\times N\) square and list them in cyclic order. These points form a polygon with

$$m=4N$$

vertices. The problem asks for the number of maximal non-crossing cut systems allowed by the square-cutting rules, with the final result reported modulo \(10^8\).

Mathematical Approach

1. Boundary Points Become a Polygon

The code explicitly builds the boundary in clockwise order:

1. bottom side from \((0,0)\) to \((N,0)\),

2. right side from \((N,1)\) to \((N,N)\),

3. top side from \((N-1,N)\) to \((0,N)\),

4. left side from \((0,N-1)\) to \((0,1)\).

This gives exactly \(4N\) distinct boundary lattice points. Joining consecutive points in that cyclic order produces a simple polygon.

2. Which Chords Are Allowed?

Two vertices may always be connected if they are adjacent on the polygon boundary. Those are just polygon edges.

For non-adjacent vertices, the code uses a geometric rule:

1. if both endpoints lie on the same side of the square and are not adjacent, the chord is forbidden,

2. otherwise the chord is allowed.

So a long segment sliding along one square side is illegal, while a segment connecting different square sides is legal.

3. Why Maximal Non-Crossing Cuts Become Triangulations

Once all legal cuts are viewed as non-crossing chords of the boundary polygon, a maximal family of such chords decomposes the polygon into faces. If any face had more than three sides, one more non-crossing legal chord could still be inserted inside that face, contradicting maximality.

Therefore every maximal non-crossing admissible cut system is exactly a triangulation of the boundary polygon using only allowed diagonals.

This is the key reduction: the original cutting problem becomes a polygon-triangulation count with a forbidden-diagonal mask.

4. Interval DP Recurrence

Let \(dp[i][j]\) be the number of valid triangulations of the chain of vertices

$$v_i,v_{i+1},\dots,v_j,$$

where indices are taken in the linear order of the opened polygon. If the closing edge \((i,j)\) is forbidden, then

$$dp[i][j]=0.$$

Otherwise we choose the third vertex \(k\) of the triangle adjacent to edge \((i,j)\). This splits the region into two smaller subpolygons, giving

$$dp[i][j]=\sum_{k=i+1}^{j-1} dp[i][k]\;dp[k][j]\pmod{10^8}.$$

This is the standard Catalan-style triangulation recurrence, except that forbidden diagonals force many subproblems to be zero.

5. Base Cases

If \(j=i+1\), the chain contains only one polygon edge and no area to triangulate, so

$$dp[i][i+1]=1.$$

This is the neutral multiplicative base that makes the recurrence work for larger intervals.

6. Small Validation Examples

The program contains four exact checks:

$$C(1)=2,\qquad C(2)=30,\qquad C(3)=604,\qquad C(4)=12168.$$

The case \(N=1\) is especially instructive. The boundary polygon is just a square, and both diagonals connect different square sides, so both are allowed. A square has exactly two triangulations, which explains \(C(1)=2\).

The larger values \(30,604,12168\) verify that the admissibility mask and the interval DP agree with the intended geometry for nontrivial boundary sizes.

7. Why the Threading Is Safe

The DP is filled by interval length. When computing all states with fixed length \(\ell=j-i\), every transition only reads states of smaller lengths. Therefore two states of the same length never depend on one another.

This is why the code can split all intervals of a fixed length across multiple threads without race conditions on the mathematical data dependency graph.

How the Code Works

build_boundary(n) creates the \(4N\) polygon vertices.

same_side(a,b,n) checks whether two vertices lie on the same physical side of the square. Using that, the code fills an allowed matrix for every pair of vertices.

count_triangulations(n, threads) runs the interval DP modulo

$$M=10^8.$$

It computes short intervals first, then longer ones, and finally returns dp[0][m-1], the number of admissible triangulations of the full polygon.

The command-line interface supports -n N, -t THREADS, and --no-validate.

Complexity Analysis

There are \(O(m^2)\) intervals with \(m=4N\), and each interval tries \(O(m)\) split points, so the runtime is

$$O(m^3)=O(N^3).$$

The DP table and admissibility matrix each use \(O(m^2)=O(N^2)\) memory.

Further Reading

  1. Problem page: https://projecteuler.net/problem=270
  2. Polygon triangulation DP: https://en.wikipedia.org/wiki/Polygon_triangulation
  3. Catalan recurrence context: https://en.wikipedia.org/wiki/Catalan_number

Problemzusammenfassung

Die Gitterpunkte auf dem Rand eines \(N\times N\)-Quadrats werden zyklisch angeordnet. Dadurch entsteht ein Polygon mit

$$m=4N$$

Ecken. Gesucht ist die Anzahl maximaler nichtschneidender zulässiger Schnitte, modulo \(10^8\).

Mathematischer Ansatz

1. Randpunkte als Polygon

Der Code erzeugt die Randpunkte im Uhrzeigersinn. Insgesamt entstehen genau \(4N\) verschiedene Punkte, also ein einfaches Polygon.

2. Welche Diagonalen sind erlaubt?

Nachbarpunkte auf dem Polygonrand sind immer erlaubt. Für nichtadjazente Punkte gilt:

1. liegen beide auf derselben Quadratseite, ist die Verbindung verboten,

2. liegen sie auf verschiedenen Quadratseiten, ist die Verbindung erlaubt.

3. Warum maximale Schnittsysteme Triangulierungen sind

Ein maximales System nichtschneidender zulässiger Sehnen zerlegt das Randpolygon in Flächen. Hätte eine Fläche mehr als drei Seiten, könnte man darin noch eine weitere zulässige nichtschneidende Sehne einziehen. Das widerspricht der Maximalität.

Also entspricht jedes maximale Schnittsystem genau einer Triangulierung mit erlaubten Diagonalen.

4. Intervall-DP

Sei \(dp[i][j]\) die Anzahl zulässiger Triangulierungen der Kette \(v_i,\dots,v_j\). Ist die abschließende Kante \((i,j)\) verboten, dann ist

$$dp[i][j]=0.$$

Sonst wählt man den dritten Eckpunkt \(k\) des an \((i,j)\) angrenzenden Dreiecks und erhält

$$dp[i][j]=\sum_{k=i+1}^{j-1}dp[i][k]\,dp[k][j]\pmod{10^8}.$$

5. Basisfälle

Für \(j=i+1\) gibt es keinen Innenraum zu triangulieren, daher

$$dp[i][i+1]=1.$$

6. Kleine Prüfwerte

Der Code validiert

$$C(1)=2,\qquad C(2)=30,\qquad C(3)=604,\qquad C(4)=12168.$$

Bei \(N=1\) ist das Randpolygon ein Quadrat. Beide Diagonalen verbinden verschiedene Quadratseiten und sind deshalb erlaubt; ein Quadrat hat genau zwei Triangulierungen.

7. Warum Parallelisierung möglich ist

Die DP wird nach Intervalllänge aufgebaut. Zustände gleicher Länge lesen nur kürzere Intervalle und hängen daher nicht voneinander ab. Genau deshalb können Intervalle gleicher Länge sicher auf Threads verteilt werden.

Funktionsweise des Codes

build_boundary(n) erzeugt die \(4N\) Eckpunkte. same_side erkennt, ob zwei Punkte auf derselben Quadratseite liegen. Damit wird die Matrix allowed aufgebaut.

count_triangulations berechnet die Intervall-DP modulo

$$M=10^8$$

und liefert am Ende dp[0][m-1].

Die Kommandozeile unterstützt -n N, -t THREADS und --no-validate.

Komplexitätsanalyse

Mit \(m=4N\) gibt es \(O(m^2)\) Intervalle und pro Intervall \(O(m)\) mögliche Trennpunkte. Daher ist die Laufzeit \(O(m^3)=O(N^3)\), der Speicher \(O(m^2)=O(N^2)\).

Weiterführende Hinweise

  1. Problem: https://projecteuler.net/problem=270
  2. Polygon-Triangulierung: https://de.wikipedia.org/wiki/Triangulierung_(Geometrie)
  3. Catalan-Zahlen: https://de.wikipedia.org/wiki/Catalan-Zahl

Problem Özeti

\(N\times N\) karenin sınırındaki kafes noktaları çevresel sırayla yazıldığında

$$m=4N$$

köşeli bir çokgen elde edilir. Problem, izin verilen kesme kuralları altında oluşan maksimal, kesişmeyen kesim sistemlerinin sayısını \(10^8\) modunda istemektedir.

Matematiksel Yaklaşım

1. Sınır noktaları bir çokgene dönüşür

Kod sınır noktalarını saat yönünde üretir: alt kenar, sağ kenar, üst kenar, sol kenar. Böylece tam olarak \(4N\) farklı sınır noktası oluşur ve bunlar basit bir çokgen verir.

2. Hangi kirişler izinli?

Çokgenin komşu köşeleri arasındaki kenarlar her zaman izinlidir. Komşu olmayan iki nokta için kural şudur:

1. iki uç aynı kare kenarı üzerinde ise bağlantı yasaktır,

2. iki uç farklı kare kenarlarında ise bağlantı serbesttir.

Yani aynı kare kenarı üzerinde uzanan uzun “kesmeler” yapılamaz; gerçek iç kesmeler farklı kenarları bağlamalıdır.

3. Neden maksimal kesim sistemi = üçgenleme?

İzinli ve kesişmeyen her kesim, sınır çokgeninin bir kirişidir. Böyle kirişlerin maksimal bir kümesi çokgeni alt yüzlere böler. Eğer bu yüzlerden biri üçgenden büyük olsaydı, o yüzün içine bir kiriş daha eklenebilirdi; bu da maksimal olma durumuna aykırıdır.

Dolayısıyla problem, yasak köşegen maskeli bir çokgen üçgenleme sayımına indirgenir.

4. Aralık DP bağıntısı

\(dp[i][j]\), \(v_i,\dots,v_j\) zincirinin geçerli üçgenleme sayısı olsun. Eğer \((i,j)\) kapanış kenarı yasaksa

$$dp[i][j]=0$$

olur. Aksi halde, \((i,j)\) kenarına komşu üçgenin üçüncü köşesi \(k\) seçilerek

$$dp[i][j]=\sum_{k=i+1}^{j-1} dp[i][k]\;dp[k][j]\pmod{10^8}$$

bağıntısı elde edilir. Bu, Catalan tipindeki standart çokgen üçgenleme bağıntısıdır; fark, bazı köşegenlerin en baştan yasak olmasıdır.

5. Taban durum

\(j=i+1\) olduğunda içeride üçgenlenecek bir alan yoktur, bu yüzden

$$dp[i][i+1]=1$$

alınır.

6. Küçük doğrulama örnekleri

Program şu dört değeri kontrol eder:

$$C(1)=2,\qquad C(2)=30,\qquad C(3)=604,\qquad C(4)=12168.$$

\(N=1\) durumu özellikle öğreticidir. Bu durumda sınır çokgeni bir kareden ibarettir ve iki köşegenin ikisi de farklı kare kenarlarını bağladığı için izinlidir. Bir karenin tam iki üçgenlemesi vardır; bu da \(C(1)=2\)'yi açıklar.

7. Neden çoklu iş parçacığı güvenli?

DP, aralık uzunluğuna göre doldurulur. Sabit bir uzunluktaki tüm durumlar yalnızca daha kısa aralıklara bakar; aynı uzunluktaki başka bir duruma bağımlılık yoktur. Bu yüzden aynı uzunluk katmanındaki aralıklar thread'lere güvenle dağıtılabilir.

Kodun Çalışma Mantığı

build_boundary(n) ile \(4N\) köşe üretilir. same_side iki noktanın karenin aynı kenarında olup olmadığını test eder. Bu bilgiyle allowed matrisi doldurulur.

count_triangulations aralık DP'sini

$$M=10^8$$

modunda hesaplar ve sonunda tüm çokgen için sonucu veren dp[0][m-1] değerini döndürür.

Komut satırı seçenekleri: -n N, -t THREADS, --no-validate.

Karmaşıklık Analizi

\(m=4N\) için \(O(m^2)\) aralık vardır ve her aralıkta \(O(m)\) bölme noktası denenir. Toplam süre \(O(m^3)=O(N^3)\), bellek kullanımı \(O(m^2)=O(N^2)\) olur.

İleri Okuma

  1. Problem metni: https://projecteuler.net/problem=270
  2. Çokgen üçgenleme: https://tr.wikipedia.org/wiki/Üçgenleme
  3. Catalan sayıları: https://tr.wikipedia.org/wiki/Catalan_sayıları

Resumen del Problema

Los puntos de la frontera de un cuadrado \(N\times N\), listados en orden cíclico, forman un polígono con

$$m=4N$$

vértices. Se pide contar los sistemas máximos de cortes no cruzados permitidos por la geometría del problema, módulo \(10^8\).

Enfoque Matemático

1. Los puntos de la frontera forman un polígono

El código recorre la frontera en sentido horario y obtiene exactamente \(4N\) puntos distintos. Al unir consecutivos se obtiene un polígono simple.

2. Qué cuerdas están permitidas

Los lados del polígono siempre se permiten. Para vértices no adyacentes:

1. si ambos están en el mismo lado del cuadrado, la cuerda está prohibida,

2. si están en lados distintos, la cuerda está permitida.

3. Por qué un sistema maximal equivale a una triangulación

Un conjunto maximal de cuerdas admisibles y no cruzadas divide el polígono en caras. Si alguna cara tuviera más de tres lados, todavía se podría añadir otra cuerda no cruzada dentro de ella. Eso contradice la maximalidad.

Por tanto, el problema se reduce a contar triangulaciones del polígono con una máscara de diagonales prohibidas.

4. DP por intervalos

Sea \(dp[i][j]\) el número de triangulaciones válidas de la cadena \(v_i,\dots,v_j\). Si la arista de cierre \((i,j)\) está prohibida, entonces

$$dp[i][j]=0.$$

Si está permitida, elegimos el tercer vértice \(k\) del triángulo adyacente a \((i,j)\) y obtenemos

$$dp[i][j]=\sum_{k=i+1}^{j-1}dp[i][k]\,dp[k][j]\pmod{10^8}.$$

5. Casos base

Cuando \(j=i+1\), no hay área interior que triangular, así que

$$dp[i][i+1]=1.$$

6. Valores pequeños de validación

El programa comprueba

$$C(1)=2,\qquad C(2)=30,\qquad C(3)=604,\qquad C(4)=12168.$$

El caso \(N=1\) es el más claro: el polígono es un cuadrado, ambas diagonales conectan lados distintos del cuadrado y por tanto son válidas; un cuadrado tiene exactamente dos triangulaciones.

7. Por qué el paralelismo es correcto

La DP se rellena por longitud de intervalo. Todas las transiciones de una longitud fija solo leen intervalos más cortos. Por eso los estados de la misma longitud pueden repartirse entre hilos sin dependencia matemática entre ellos.

Cómo funciona el código

build_boundary construye los \(4N\) vértices. same_side decide si dos puntos están en el mismo lado físico del cuadrado, y con ello se llena la matriz allowed.

count_triangulations ejecuta la DP módulo

$$M=10^8$$

y devuelve dp[0][m-1].

La interfaz admite -n N, -t THREADS y --no-validate.

Complejidad

Con \(m=4N\), hay \(O(m^2)\) intervalos y \(O(m)\) puntos de división por intervalo. El tiempo total es \(O(m^3)=O(N^3)\) y la memoria \(O(m^2)=O(N^2)\).

Lecturas

  1. Problema: https://projecteuler.net/problem=270
  2. Triangulación de polígonos: https://es.wikipedia.org/wiki/Triangulación
  3. Números de Catalán: https://es.wikipedia.org/wiki/Número_de_Catalan

问题概述

把 \(N\times N\) 正方形边界上的格点按循环顺序列出来,会得到一个有

$$m=4N$$

个顶点的多边形。题目要求统计所有满足规则的“最大不相交切割系统”的数量,并对 \(10^8\) 取模。

数学方法

1. 边界格点变成一个多边形

代码按顺时针顺序走完四条边,得到恰好 \(4N\) 个不同的边界点,把相邻点连起来后就得到一个简单多边形。

2. 哪些弦是允许的?

多边形的边总是允许。对不相邻顶点:

1. 若两点位于正方形的同一条边上,则这条弦被禁止,

2. 若两点位于不同边上,则这条弦允许。

3. 为什么最大切割系统等价于三角剖分

把所有合法切割看成边界多边形中的不相交弦后,一个极大的合法弦集合会把多边形分成若干面。若其中某一面有超过三条边,那么还可以在这面内部再加入一条不相交合法弦,这与“极大”矛盾。

因此,每个最大不相交切割系统都恰好对应于一个只使用允许对角线的三角剖分。

4. 区间 DP 递推

设 \(dp[i][j]\) 表示链 \(v_i,\dots,v_j\) 的合法三角剖分数量。若闭合边 \((i,j)\) 本身不允许,则

$$dp[i][j]=0.$$

若允许,则选择与边 \((i,j)\) 相邻三角形的第三个顶点 \(k\),递推式为

$$dp[i][j]=\sum_{k=i+1}^{j-1}dp[i][k]\;dp[k][j]\pmod{10^8}.$$

5. 初值

当 \(j=i+1\) 时,链内部没有面积需要继续剖分,所以

$$dp[i][i+1]=1.$$

6. 小型校验值

程序内置了四个精确检查:

$$C(1)=2,\qquad C(2)=30,\qquad C(3)=604,\qquad C(4)=12168.$$

\(N=1\) 最直观:此时边界多边形就是一个正方形,两条对角线都连接不同的方形边,因此都允许;而正方形恰有两种三角剖分。

7. 为什么同长度状态可以并行

DP 按区间长度递增填表。固定长度的一层只会读取更短区间的结果,因此同一层内的状态彼此没有依赖关系。这正是代码可以把同长度区间分配给多个线程的原因。

代码如何工作

build_boundary 构造 \(4N\) 个顶点。same_side 用来判断两个点是否在正方形的同一物理边上,并据此填充 allowed 矩阵。

count_triangulations

$$M=10^8$$

模下运行区间 DP,并返回 dp[0][m-1]

命令行选项包括 -n N-t THREADS--no-validate

复杂度分析

当 \(m=4N\) 时,有 \(O(m^2)\) 个区间,每个区间尝试 \(O(m)\) 个分割点,因此总时间为 \(O(m^3)=O(N^3)\),空间为 \(O(m^2)=O(N^2)\)。

延伸阅读

  1. 题目页面: https://projecteuler.net/problem=270
  2. 多边形三角剖分: https://zh.wikipedia.org/wiki/三角剖分
  3. Catalan 数: https://zh.wikipedia.org/wiki/卡塔兰数

Краткое описание

Граничные узлы квадрата \(N\times N\), перечисленные по кругу, образуют многоугольник с

$$m=4N$$

вершинами. Требуется посчитать число максимальных непересекающихся допустимых разрезов по модулю \(10^8\).

Математический подход

1. Граница превращается в многоугольник

Код проходит по четырём сторонам квадрата по часовой стрелке и получает ровно \(4N\) различных граничных точек. Последовательное соединение этих точек даёт простой многоугольник.

2. Какие хорды допустимы?

Рёбра многоугольника допустимы всегда. Для не соседних вершин действует правило:

1. если обе точки лежат на одной стороне квадрата, хорда запрещена,

2. если точки лежат на разных сторонах, хорда разрешена.

3. Почему максимальные разрезы дают триангуляцию

Максимальное множество допустимых непересекающихся хорд разбивает многоугольник на грани. Если бы какая-то грань имела больше трёх сторон, внутрь неё можно было бы провести ещё одну допустимую хорду. Это противоречит максимальности.

Значит, задача сводится к подсчёту триангуляций многоугольника с маской запрещённых диагоналей.

4. Интервальный DP

Пусть \(dp[i][j]\) обозначает число допустимых триангуляций цепочки \(v_i,\dots,v_j\). Если замыкающая хорда \((i,j)\) запрещена, то

$$dp[i][j]=0.$$

Иначе выбирается третий вершина \(k\) треугольника, прилегающего к \((i,j)\), и получается

$$dp[i][j]=\sum_{k=i+1}^{j-1}dp[i][k]\,dp[k][j]\pmod{10^8}.$$

5. База

При \(j=i+1\) внутренней области нет, поэтому

$$dp[i][i+1]=1.$$

6. Малые проверочные значения

Программа проверяет

$$C(1)=2,\qquad C(2)=30,\qquad C(3)=604,\qquad C(4)=12168.$$

Случай \(N=1\) особенно прост: многоугольник есть квадрат, обе его диагонали соединяют разные стороны квадрата и потому допустимы. У квадрата ровно две триангуляции.

7. Почему распараллеливание корректно

Таблица DP заполняется по длине интервала. Состояния фиксированной длины читают только более короткие интервалы, поэтому между ними нет зависимостей. Именно поэтому интервалы одной длины можно безопасно раздавать разным потокам.

Как работает код

build_boundary строит \(4N\) вершин. same_side определяет, лежат ли две точки на одной физической стороне квадрата. На основе этого заполняется матрица allowed.

count_triangulations выполняет интервальный DP по модулю

$$M=10^8$$

и в конце возвращает dp[0][m-1].

Поддерживаются параметры -n N, -t THREADS и --no-validate.

Сложность

При \(m=4N\) существует \(O(m^2)\) интервалов, и для каждого перебирается \(O(m)\) точек разреза. Итого время \(O(m^3)=O(N^3)\), память \(O(m^2)=O(N^2)\).

Дополнительные материалы

  1. Условие: https://projecteuler.net/problem=270
  2. Триангуляция многоугольника: https://ru.wikipedia.org/wiki/Триангуляция
  3. Числа Каталана: https://ru.wikipedia.org/wiki/Числа_Каталана

ملخص المسألة

إذا رتبنا نقاط الشبكة على حدود مربع \(N\times N\) ترتيبًا دائريًا، حصلنا على مضلع له

$$m=4N$$

رؤوس. المطلوب هو عدّ جميع أنظمة القطع المسموحة غير المتقاطعة التي تكون عظمى، ثم أخذ الناتج بتعديل \(10^8\).

المنهج الرياضي

1. نقاط الحد تتحول إلى مضلع

يمر الكود على أضلاع المربع الأربعة بترتيب دائري ويولد بالضبط \(4N\) نقاط حدية مختلفة. وصل هذه النقاط بالتتابع يعطي مضلعًا بسيطًا.

2. ما الأوتار المسموحة؟

أضلاع المضلع مسموحة دائمًا. أما بين رأسين غير متجاورين فالقانون هو:

1. إذا كانا على الضلع نفسه من أضلاع المربع فالوصل ممنوع،

2. إذا كانا على ضلعين مختلفين فالوصل مسموح.

3. لماذا تعني المنظومة العظمى تثليثًا؟

إذا أخذنا مجموعة عظمى من الأوتار المسموحة غير المتقاطعة، فإنها تقسم المضلع إلى مناطق. ولو كانت إحدى هذه المناطق ذات أكثر من ثلاثة أضلاع، لأمكن إدخال وتر إضافي غير متقاطع داخلها. وهذا يناقض العظمى.

إذن المسألة تكافئ عدّ تثليثات المضلع مع وجود قناع للأقطار الممنوعة.

4. البرمجة الديناميكية على الفواصل

لتكن \(dp[i][j]\) عدد التثليثات المسموحة للسلسلة \(v_i,\dots,v_j\). إذا كان الوتر \((i,j)\) ممنوعًا، فإن

$$dp[i][j]=0.$$

أما إذا كان مسموحًا، فنختار الرأس الثالث \(k\) للمثلث الملاصق للضلع \((i,j)\)، فنحصل على

$$dp[i][j]=\sum_{k=i+1}^{j-1}dp[i][k]\,dp[k][j]\pmod{10^8}.$$

5. حالة الأساس

عندما \(j=i+1\) لا توجد مساحة داخلية تحتاج إلى تثليث، لذا

$$dp[i][i+1]=1.$$

6. قيم تحقق صغيرة

يتحقق البرنامج من القيم

$$C(1)=2,\qquad C(2)=30,\qquad C(3)=604,\qquad C(4)=12168.$$

في حالة \(N=1\) يكون المضلع مجرد مربع، وكلا قطريه يصل بين ضلعين مختلفين من أضلاع المربع، ولذلك كلاهما مسموح. والمربع له تثليثان بالضبط.

7. لماذا التوازي صحيح هنا؟

تملأ DP حسب طول الفاصل. الحالات ذات الطول نفسه تعتمد فقط على فواصل أقصر، ولا تعتمد على بعضها بعضًا. لهذا يمكن توزيع فواصل الطول الواحد على عدة خيوط تنفيذ بأمان.

كيف يعمل الكود

build_boundary يبني الرؤوس \(4N\). وتحدد الدالة same_side ما إذا كانت نقطتان تقعان على الضلع الفيزيائي نفسه من المربع. وبناءً على ذلك تُملأ مصفوفة allowed.

count_triangulations يشغل DP على الفواصل بتعديل

$$M=10^8$$

ويعيد في النهاية القيمة dp[0][m-1].

تدعم الواجهة الوسائط -n N و-t THREADS و--no-validate.

تحليل التعقيد

عندما \(m=4N\)، يوجد \(O(m^2)\) فاصلًا، ولكل فاصل \(O(m)\) نقاط فصل ممكنة. لذا يكون الزمن \(O(m^3)=O(N^3)\)، والذاكرة \(O(m^2)=O(N^2)\).

مراجع إضافية

  1. صفحة المسألة: https://projecteuler.net/problem=270
  2. تثليث المضلعات: https://ar.wikipedia.org/wiki/تثليث
  3. أعداد كاتالان: https://ar.wikipedia.org/wiki/عدد_كاتالان