演算法簡述
凸優化是乙個神奇的東西,通過加權,二分權值,把數量限制去掉,從而優化dp,或者其他很難滿足的限制
這裡有講解和證明
wqs的**
這個東西bytedance冬令營時就學了,但是沒有完全掌握。今天再翻以前的題,竟然沒有立即反應過來。
趕快複習,然後寫幾份**!
學習演算法不能偷懶,一定要實現!還要定期複習!否則會忘的!
例題
cf739e gosha is hunting一定要注意精度!首先這道題可以費用流。只需要把兩個同時選多出的貢獻:ui * pi在第二個流量的費用中減去。
然後費用流可以用貪心和資料結構維護,cf官方題解,然而似乎很麻煩,不想看
這道題的神奇之處是wqs二分
詳細題解
一點點的差距都會導致多選乙個物品,必須使用eps,並且保證cost稍微多一點(使用二分後的r,用l會掛!),否則會**
最後因為此題膠囊肯定用完更好,就直接貢獻+a * ca+b * cb,不要用最後一次dp的選的個數。二分的時候輸出一下選的個數就會發現一直在不規則跳動(a,a + 1),好像不會收斂。因為精度有很大問題!
整數二分不靠譜,至少!1e9+7這個質數還不夠大,好像直接小數二分50次更好一些
wa了無數發的血的教訓!
#include
using namespace std;
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define rvc(i,s) for(register int i = 0 ; i < (int)s.size() ; i++)
#define rvcd(i,s) for(register int i = ((int)s.size()) - 1 ; i >= 0 ; i--)
#define fore(i,x)for (register int i = head[x] ; i ; i = e[i].next)
#define forup(i,l,r) for (register int i = l ; i <= r ; i += lowbit(i))
#define fordown(i,id) for (register int i = id ; i ; i -= lowbit(i))
#define pb push_back
#define prev prev_
#define stack stack_
#define mp make_pair
#define fi first
#define se second
#define lowbit(x) ((x)&(-(x)))
#define eps 1e-10
typedef
long
long ll;
typedef
long
double ld;
typedef
unsigned
long
long ull;
typedef pairdouble
> pr;
const
double inf =
2e8;
const
int n =
3e6+10;
const
int maxn =
100020
;const ll mod =
1e9+7;
double p[maxn]
,u[maxn]
,f[maxn]
;int n,a,b,numa[maxn]
,numb[maxn]
;bool check2
(double ca,
double cb)
if( f[i -1]
+ u[i]
- cb - eps > f[i])if
( f[i -1]
+ p[i]
- ca + u[i]
- cb - u[i]
* p[i]
- eps > f[i])}
return numb[n]
<= b;
}double
check
(double ca)
return r;
//必須return上界,就算l和r有非常細微的差距(1e-15),都有可能導致多選乙個物品。必須讓cost稍微大一點
}void
solve()
// cout(r,cb)
;// rep(i,1,n) cout("%.10lf\n"
,f[n]+(
double
)r * a +
(double
)cb * b)
;// cout<}
intmain()
[bzoj5311]-[codeforces321e]ciel and gondolas-dp凸優化 / dp決策分治 / 類四邊形優化注意:這道題很經典,可以用決策單調性做。
用凸優化+決策單調性做到nlogklogsum+n2 , 雖然沒有直接四邊形不等式優化,
但是算是一道經典的用凸優化簡化個數限制的模型
最後無論是否取到k個,都要減去k * cost的答案,因為是+cost之後才取#include
using namespace std;
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define rvc(i,s) for(register int i = 0 ; i < (int)s.size() ; i++)
#define rvcd(i,s) for(register int i = ((int)s.size()) - 1 ; i >= 0 ; i--)
#define fore(i,x)for (register int i = head[x] ; i ; i = e[i].next)
#define forup(i,l,r) for (register int i = l ; i <= r ; i += lowbit(i))
#define fordown(i,id) for (register int i = id ; i ; i -= lowbit(i))
#define pb push_back
#define prev prev_
#define stack stack_
#define mp make_pair
#define fi first
#define se second
#define lowbit(x) ((x)&(-(x)))
#define eps 1e-10
typedef
long
long ll;
typedef
long
double ld;
typedef
unsigned
long
long ull;
typedef pair<
int,
int> pr;
const
int inf =
2e8;
const
int n =
3e6+10;
const
int maxn =
4020
;const ll mod =
1e9+7;
int sum[maxn]
[maxn]
,a[maxn]
[maxn]
;int f[maxn]
,num[maxn]
;pr st[maxn]
;int tops,n,k;
inline
intread()
void
init()
}inline
intgetsum
(int l,
int r)
inline
intcalcw
(int id,
int p)
inline
void
insert
(int id)
int l = st[tops]
.se +
1,r = n,res =0;
while
( l <= r )
if( res )
}inline bool cmp
(pr p1,pr p2)
inline
intquery
(int pos)
bool check
(int mid)
// cout<<" check : "<= k;
}void
solve()
check
(cost)
;// cout("%d\n"
,f[n]
-(k * cost));
}int
main()
斜率優化DP小結(含凸優化)
目錄我看了很多 d a l a o的部落格,使我對其印象深刻。確實,斜率優化的dp式一般都是 f i min f j a i a j 我們對於k f j a i a j f j f k f j f k f j f k a k a j 所以,任何形式我們都可以轉化成斜率式,以便二分。下面是我從我看的第...
凸優化基礎知識
一.凸函式相關定義 1.首先定義凸集,如果x,y 屬於某個集合 c,並且所有的 也屬於c,那麼c 為乙個凸集 2.進一步,如果乙個函式其定義域是凸集,並且 則該函式為凸函式。上述條件還能推出更一般的結果,3.如果函式有二階導數,那麼如果函式二階導數為正,或者對於多元函式,hessian 矩陣半正定則...
凸優化 非凸優化
凸 convex vs 非凸的概念,數學定義就不寫了,介紹個直觀判斷乙個集合是否為convex的方法,如下圖 簡單的測試乙個集合是不是凸的,只要任意取集合中的倆個點並連線,如果說連線段完全被包含在此集合中,那麼這個集合就是凸集,例如左圖所示。凸優化有個非常重要的定理,即任何區域性最優解即為全域性最優...