NOI2007 貨幣兌換

2022-03-27 03:32:56 字數 1462 閱讀 2223

題目

先來畫一畫柿子

設\(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...