題目
先來畫一畫柿子
設\(dp_i\)表示你第\(i\)天之後最多剩下多少錢
考慮一下對於\(i\)的轉移,我們肯定要在之前列舉一天\(j\)這一天把所有的東西買進來,之後在\(i\)天賣掉
設那天買進\(a\)的量為\(d_a\),買進\(b\)的量為\(d_b\)
我們可以得到這樣的方程
\[d_ap_a+d_bp_b=dp_j
\]\[d_a:d_b=r_j:1
\]來愉快的解方程吧
\[d_a=d_br_j
\]\[r_jd_bp_a+d_bp_b=dp_j
\]\[d_b(r_jp_a+p_b)=dp_j
\]\[d_b=\frac
\]\[d_a=\frac
\]那麼我們從\(i\)天賣出收益就是
\[dp_i=p_\frac+p_}+p_\frac+p_}
\]那就是求乙個點積最大值啊
考慮凸殼來優化
\[dp_i=p_ad_a+p_bd_b
\]\[\frac=\fracd_a+d_b
\]\[-\fracd_a+\frac=d_b
\]斜率為\(-\frac\)的直線去卡凸殼上的點,最大化乙個截距就好了
由於什麼也不單調,選擇用\(cdq\)分治來維護這個\(dp\)
**
#include#include#include#include# include #define maxn 100005
#define re register
#define ll long long
#define double double
#define eps 1e-10
#define max(a,b) ((a)>(b)?(a):(b))
int n,h=1,t,q[maxn];
double pa[maxn],pb[maxn],ra[maxn];
struct nodea[maxn];
double dp[maxn],x[maxn],y[maxn];
inline int cmp(node a,node b)
return q[l];
}void cdq(int l,int r)
int mid=l+r>>1;
cdq(l,mid);std::sort(a+l,a+mid+1,cmp);h=1,t=0;
for(re int i=l;i<=mid;i++) ins(a[i].rk);
for(re int i=mid+1;i<=r;i++)
cdq(mid+1,r);
}int main()
for(re int i=1;i<=n;i++) a[i].rk=i;
cdq(1,n);
printf("%.3lf\n",(double)dp[n]);
return 0;
}
NOI2007 貨幣兌換
今天聽了crazy和samjia的noi雜 砸 題選講,感覺自己萌萌噠 於是就來怡情地寫了這道題。額 o 這個不好說啊。語文不好不好裱我 還是貼圖吧。咳咳,希望大家都看懂題了。乙個很明顯的貪心思路就是,我們每天要不全買,要不全賣。因為一有利益我們就去佔,一有虧損我們就不碰。那麼我們可以有dp方程 f...
Noi2007 貨幣兌換
傳送門 小半個上午 一下午都給了這題了qaq 都知道是斜率優化,問題是我看這題根本就是乙個人乙個式子啊 算了,把我的過程列出來吧 令 f i 表示第i天結束時強制賣出所有金券最多能得到的軟妹幣數量,列舉上一次 金券的時間,就有 beginf i max end 這裡沒有寫隱含條件 f i ge f ...
NOI2007 貨幣兌換
設 dp i a i b i x i y i 為第 i 天時的最大收益 a卷 b卷 將所有現金兌成a卷數量 b卷 於是有 dp i max dp i 1 x j a i y j b i 然後可以寫成斜率優化形式 y j fracx j frac 對於每個點 x j y j 我們用一根斜率為 frac...