简要题意:
求在 \(n\) 个点中满足每 \(3\) 个点不两两有边的最多边数。
首先,这题 \(\text{dp}\) 没有头绪,所以只能手动找规律。
\(\texttt{n}\) | \(0\) | \(1\) | \(2\) | \(3\) | \(4\) | \(5\) | \(6\) |
---|---|---|---|---|---|---|---|
\(\texttt{ans}\) | \(0\) | \(0\) | \(1\) | \(2\) | \(4\) | \(6\) | \(9\) |
如果你不明白,这里给出 \(n>3\) 的所有构造图(\(n \leq 3\) 就不用画图了吧)
\(n=4\) 时答案为 \(4\):
\(n=5\) 时答案为 \(6\):
\(n=6\) 时答案为 \(9\):
所以,我们在看一眼这个表格:
\(\texttt{n}\) | \(0\) | \(1\) | \(2\) | \(3\) | \(4\) | \(5\) | \(6\) |
---|---|---|---|---|---|---|---|
\(\texttt{ans}\) | \(0\) | \(0\) | \(1\) | \(2\) | \(4\) | \(6\) | \(9\) |
然后,因为我们觉得可以 \(O(1)\) 用公式计算,盲猜它次数应该不会超过 \(4\) 次,所以就假设答案 \(f_x = ax^4 + bx^3 + cx^2+dx+ e\).
然后得到方程组:
\[ \begin{cases} a + b + c + d + e = 0 \\ 16a + 8b + 4c + 2d + e = 1 \\ 81a + 27b + 9c + 3d + e = 2 \\ 256a + 64b + 16c + 4d + e = 4 \\ 625a + 125b + 25c + 5d + e = 6 \\ 1256a + 216b + 36c + 6d + e = 9 \end{cases} \]
(好像还多了一道方程)
你发现答案 近似 为:
\[ \begin{cases} a=0 \\ b=0 \\ c=\frac{1}{4} \\ d=0 \\ e=0 \end{cases} \]
即答案为 \(\bigg( \frac{ n^2}{4} \bigg )\).
你整理一下发现,答案其实是:
\[\bigg \lfloor \frac{n^2}{4} \bigg \rfloor \]
然后你就用 \(O(1)\) 解决了问题。
下面给出一个 严谨 一点的解法。
下面资料来自 百度百科——托兰定理
设 \(A\) 为 \(N\) 个点中,向外连线最多的点,设它向外连 \(k\) 条线,则与 \(A\) 相连的点之间不允许连线
而剩余 \(N-1-k\) 中的任意一点不可能向外连线数大于 \(k\),设这些点连线总数为 \(y\),则有
\(y≤k(N-1-k)+k\)
\(y≤-k^2+Nk=-(k-N/2)^2+ \lfloor N^2/4 \rfloor\)
当 \(k= \lfloor N/2 \rfloor\) 时,\(y\) 是整数,所以 \(y\)的最大值为\(\lfloor N^2/4 \rfloor\)
所以 \(y≤ \lfloor N^2/4 \rfloor\)
得证。
时间复杂度:\(O(1)\).
实际得分:\(100pts\).
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
int main(){
int n=read();
printf("%d\n",n*n/4);
return 0;
}