【NOI2012】骑行川藏【拉格朗日乘数法】【二分套二分】
生活随笔
收集整理的這篇文章主要介紹了
【NOI2012】骑行川藏【拉格朗日乘数法】【二分套二分】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
拉格朗日乘數法裸題
限制
f({v})=∑i=1nkisi(vi?vi′)=EUf(\{v\})=\sum_{i=1}^nk_is_i(v_i-v_i')=E_Uf({v})=i=1∑n?ki?si?(vi??vi′?)=EU?
求
g({v})=∑i=1n=sivig(\{v\})=\sum_{i=1}^n=\frac{s_i}{v_i}g({v})=i=1∑n?=vi?si??
最小值
設
L(λ,{v})=g({v})+λ[f({v})?EU]=∑i=1n[sivi+λkisi(vi?vi′)2]?λEUL(\lambda,\{v\})=g(\{v\})+\lambda[f(\{v\})-E_U]\\=\sum_{i=1}^n[\frac{s_i}{v_i}+\lambda k_is_i(v_i-v_i')^2]-\lambda E_UL(λ,{v})=g({v})+λ[f({v})?EU?]=i=1∑n?[vi?si??+λki?si?(vi??vi′?)2]?λEU?
對于viv_ivi?的偏導數為000,跳若干步后
ki(vi?vi′)vi2=xk_i(v_i-v_i')v_i^2=xki?(vi??vi′?)vi2?=x
二分xxx再二分viv_ivi?并計算是否為EUE_UEU?即可
#include <iostream> #include <cstdio> #include <cstring> #include <cctype> #define MAXN 10005 using namespace std; double s[MAXN],k[MAXN],v[MAXN],v_[MAXN],E; int n; inline double solve(int i,double x) {x/=k[i];double l=0,r=1e5,mid;for (int T=1;T<=100;T++){mid=(l+r)/2;if ((mid-v_[i])*mid*mid<x) l=mid;else r=mid;}return v[i]=l; } inline bool check(double x) {double sum=0;for (int i=1;i<=n;i++){solve(i,x);sum+=k[i]*s[i]*(v[i]-v_[i])*(v[i]-v_[i]);}return sum<E; } int main() {scanf("%d%lf",&n,&E);for (int i=1;i<=n;i++) scanf("%lf%lf%lf",&s[i],&k[i],&v_[i]);double l=0,r=1e5,mid;for (int i=1;i<=100;i++){mid=(l+r)/2;if (check(mid)) l=mid;else r=mid;}double ans=0;for (int i=1;i<=n;i++) ans+=s[i]/solve(i,l);printf("%.8f",ans);return 0; }總結
以上是生活随笔為你收集整理的【NOI2012】骑行川藏【拉格朗日乘数法】【二分套二分】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【NOI2016】国王饮水记【贪心】【斜
- 下一篇: 音视频技术开发周刊 | 136