微积分相关

拉格朗日乘数法

对于多元函数 \(f(x_1,x_2,\dots,x_n)\),有若 \(m\) 个约束条件形如:\(g_i(x_1,x_2,\dots,x_n)=0\)

我们要求 \(f\) 在约束条件下的极值。

首先,对与一元情况,我们只要找到所有导数为 \(0\) 的点即可。

对于多元和约束,我们构造函数 \(L(x_1, x_2, \dots , x_n, \lambda)\)\(\lambda\) 是实数:

\[L(x_1, x_2, \dots , x_n, \lambda)=f(x_1,x_2,\dots,x_n)+\lambda(\sum_{i=1}^mg(x_1, x_2, \dots , x_n)) \]

对于这个函数,我们求出对 \(x_1,x_2,\dots,x_n\) 求出他们的偏微分,要求每个偏微分都等于 \(0\) 并且 \(\lambda\) 的偏微分也是 \(0\)(这样就相当于 \(g\)\(0\))。

即满足方程组:

\[\begin{cases} \frac{\partial L}{\partial x_1}=0\\ \frac{\partial L}{\partial x_2}=0\\ \,\,\,\,\,\vdots\\ \frac{\partial L}{\partial x_n}=0\\ \frac{\partial L}{\partial \lambda}\,\,=0\\ \end{cases} \]

求出这个方程组的所有解就是可能的极值。

例1: 过河问题:有一条河,分成三段,每段水流速度分别为 \(v_1,v_2,v_3\),宽度分别为 \(w_1, w_2, w_3\),现在要从东岸到西岸,以恒定的速度 \(v\) 过河,要求上岸点和出发地点在同一垂直于河流的直线上,求最少时间。

思路:

显然这个问题中的变量是各段出发的角度,不妨设偏移的角度分别是 \(\theta_1,\theta_2,\theta_3\)

通过对速度分解,表示过河时间的函数为:

\[f(\theta_1,\theta_2,\theta_3)= \frac{w_1}{v\cos\theta_1}+ \frac{w_2}{v\cos\theta_2}+ \frac{w_3}{v\cos\theta_3} \]

约束为:

\[g(\theta_1,\theta_2,\theta_3)= \frac{w_1}{v\cos\theta_1}(v_1-v\sin\theta_1)+ \frac{w_2}{v\cos\theta_2}(v_2-v\sin\theta_2)+ \frac{w_3}{v\cos\theta_3}(v_3-v\sin\theta_3) \]

于是我们可以用拉格朗日乘数法,引入实数 \(\lambda\),构造函数 \(L(\theta_1,\theta_2,\theta_3,\lambda)\)

我们考虑对 \(\theta_1,\theta_2,\theta_3,\lambda\) 求偏微分。

首先,求导中有结论:

\[(\frac{u}{v})'=\frac{u'v-uv'}{v^2} \]

先对 \(\theta_1\) 求导,显然只有 \(\frac{w_1}{v\cos\theta_1}\)\(\frac{w_1}{v\cos\theta_1}(v_1-v\sin\theta_1)\lambda\) 有影响。

第一个,\(\cos\) 的导数是 \(-\sin\),再根据结论:

\[(\frac{w_1}{v\cos\theta_1})'=\frac{w_1\sin \theta_1}{v\cos^2 \theta_1} \]

第二个,同理:

\[\begin{aligned} (\frac{w_1}{v\cos\theta_1}(v_1-v\sin\theta_1)\lambda)' &= \frac{w_1\sin \theta_1}{v\cos^2 \theta_1}\lambda v_1 -\frac{\lambda w_1}{\cos^2\theta_1}\\ \end{aligned} \]

所以它的偏微分就是:

\[\frac{w_1\sin \theta_1}{v\cos^2 \theta_1}(1+\lambda v_1) -\frac{\lambda w_1}{\cos^2\theta_1} \]

要求其等于 \(0\),化简就可以得到:

\[\sin \theta_1(1+\lambda v_1)=\lambda v \]

其他同理,我们就可以得到一个方程组,解开就行了。

怎么解还不会,咕咕咕咕。

例2: 平面上有若干个点,距离原点距离分别为 \(r_1,r_2,\dots,r_n\),要求形成凸包面积最大。

思路:

同理,也是以角度为变量,以和为 \(2\pi\) 为约束即可。

最终可以得出方程组,与 \(\lambda\) 有单调性,二分 \(\lambda\) 即可求出答案。

例3: 三位平面上 \(n\) 个点 \((a_1,b_1,c_1),\dots,(a_n,b_n,c_n)\),要求求一条直线 \(L\) 使得投影在这条直线上后所有值的方差最大。

思路:

学了线代再回来做。

例4: CF185B: 给定 \(S, a, b, c \in \mathbb{Z_+}\),求 \(x^ay^bz^c\) 最大值,满足 \(x,y,z \in \mathbb{R_+},0 \le x+y+z \le S\)

思路:

显然 \(x + y + z = S\) 时最好,构造 \(L(x,y,z,\lambda)=x^ay^bz^c+\lambda(x+y+z-S)\)

求出偏导可以得到:\(ax^{a-1}y^bz^c=bx^ay^{b-1}z^c=cx^ay^bz^{c-1}\)

然后求得 \(x:y:z=a:b:c\),于是结合 \(x+y+z-S\) 得到:

\[\begin{cases} x = \frac{S \times a}{a + b + c}\\ y = \frac{S \times b}{a + b + c}\\ z = \frac{S \times c}{a + b + c}\\ \end{cases} \]

就是答案。

例4: P2179 [NOI2012] 骑行川藏

思路:

练习拉格朗日乘数法的好题。

为了避免混淆,\(f_i\) 指原题中的 \(v_i'\)

我们设时间函数 \(f(v_1,v_2,\dots,v_n)=\sum_{i=1}^n\frac{s_i}{v_i}\),总能量为 \(g(v_1,v_2,\dots,v_n)=\sum_{i=1}^nk_{i}(v_i-f_i)^2s_i - E_U\)

还是构造 \(L(v_1,v_2,\dots,v_n,\lambda)=f(v_1,v_2,\dots,v_n)+\lambda g(v_1,v_2,\dots,v_n)\),然后求偏导。

\(x_i\) 求导,将所有与 \(x_i\) 有关的项拎出来:\(\frac{s_i}{v_i}+\lambda k_is_iv_i^2-2\lambda k_is_if_iv_i\)

求导变成:\(-\frac{s_i}{v_i^2}+2\lambda k_i s_i - 2 \lambda k_i s_i f_i\),我们就是要求这个式子为 \(0\)

显然可以把 \(s_i\) 除掉,整理变成:

\[v_i^2(v_i-f_i) = \frac{1}{2\lambda k_i} \]

显然 \(v_i \le 0\)\(v_i \le f_i\),左边是个递增的单调函数。

再看对于 \(g\) 的限制不难发现,\(g\)\(v_i \le \max\{0,f_i\}\) 的情况下也是递增的,于是我们可以二分 \(\lambda\),求出每个 \(v_i\) 然后判断。需要两个二分,代码很好写。

例5: 滑行 黑暗爆炸 - 3695

思路:

与例 1 类似,我们可以得到 \(f(\theta_1,\theta_2,\dots,\theta_n)=\sum_{i=1}^n\frac{h_i}{v\cos\theta_i}\)\(g(\theta_1,\theta_2,\dots,\theta_n)=\sum_{i=1}^nh_i\tan\theta_i - X\)

然后我们依然是对 \(\theta_i\) 求导,注意 \((\tan \theta_i)'=\frac{1}{\cos^2 \theta_i}\),经过整理我们就可以得到:

\[\sin \theta_i=-\lambda v_i \]

显然 \(\theta_i\) 应该在 \([0, \frac{\pi}{2})\) 中,即 \(\sin{\theta_i}\) 的值域是 \((-1,0]\),所以我们得到 \(-\frac{1}{v_i} < \lambda \le 0\),去这些左边界的最大值为二分的左边界,不难发现随 \(\lambda\) 增大 \(g\) 会减小,所以依然可以二分来做。

如果直接算可以用三角函数反三角函数,也可以用 \(\sin^2\theta+\cos^2\theta=1\) 求出 \(\cos\),进而求出 \(\tan\),相对来说精度更高,注意开方时要判断是不是负数。

点击查看代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 105;

int n, X;
long double h[N] = {0}, v[N] = {0};

long double Sqrt(long double x) {
	if (x < 0)
		return 0;
	return sqrt(x);
}

bool chk(long double x) {
	long double sum = 0;
	for (int i = 1; i <= n; i++) 
		sum += 1.0 * h[i] * ((-1.0 * x * v[i]) / Sqrt(1 - x * x * v[i] * v[i]));
	return sum >= X;
}

int main() {
	cin >> n >> X;
	for (int i = 1; i <= n; i++)
		cin >> h[i];
	long double l = -2e9, r = 0;
	for (int i = 1; i <= n; i++)
		cin >> v[i], l = max(l, -1.0 / v[i]);
	while (l + 1e-15 < r) {
		long double mid = (l + r) / 2;
		if (chk(mid))
			l = mid;
		else
			r = mid;
	}
	long double sum = 0;
	for (int i = 1; i <= n; i++) 
		sum += 1.0 * h[i] / (1.0 * v[i] * Sqrt(1 - l * l * v[i] * v[i]));
	printf("%.3Lf\n", sum);
	return 0;
}

离散微积分

\(f(x)\) 是定义在 \(\mathbb{Z}\) 上的函数时,我们定义差分(也就是导数):

\[g(x)=\Delta f(x)=f(x+1)-f(x) \]

离散积分就是:

\[\sum_{a}^{b}g(x)\delta x=\sum_{k=a}^{b-1}g(k)=f(b)-f(a) \]

与微积分基本定理类似。

接着,我们还要知道两个东西。

上阶乘幂:\(x^{\overline{m}}=x(x+1)(x+2)\dots(x+m-1)\)

下阶乘幂:\(x^{\underline{m}}=x(x-1)(x-2)\dots(x-m+1)\)

我们对下阶乘幂求离散导数就会得到:

\[\Delta x^{\underline{m}}=mx^{\underline{m-1}} \]

与幂函数求导类似。

运用这个我们还可以得到:

\[\sum_{a}^b x^{\underline{m}}\delta x=\frac{1}{m+1}x^{\underline{m+1}}|^{b}_{a} \]

例1: 求出 \(\sum_{0 \le k < n}k^2\) 的封闭形式。

思路:

可以用离散积分来做,有 \(x^2=x^{\underline{2}}+x^{\underline{1}}\),于是我们可以根据积分得出封闭形式。

这种方法可以解决任意次幂。

例2: 证明 \((a+b)^{\underline{n}}=\sum_{r=0}^n\binom{n}{r}a^{\underline{n-r}}b^{\underline{r}}\)

思路:

\(a+b\) 个球中选 \(n\) 个排成一行,double counting.

posted @ 2024-01-20 13:41  rlc202204  阅读(24)  评论(0编辑  收藏  举报