日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash

發布時間:2025/7/25 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.lydsy.com/JudgeOnline/problem.php?id=1492

?

dp[i] 表示 第i天賣完的最大收益

樸素的dp:

枚舉從哪一天買來的在第i天賣掉,或者是不操作

dp[i]=max(dp[i-1],X[j]*A[i]+Y[j]*B[i])

其中X[j]表示在第j天能買多少A紀念券,Y[j]表示在第j天能買多少B紀念券

可列方程 X[j]*A[j]+Y[j]*B[j]=dp[j]

又因為 X[j]=Rate[j]*Y[j]

所以解出 Y[j]=dp[j]/(B[j]+A[j]*Rate[j])

?

優化:

dp[i]=X[j]*A[i]+Y[j]*B[i]

Y[j]=dp[i]/B[i] - A[i]/B[i] * x[j]

斜率優化形式,維護上凸殼,最大化截距

點:(X[j],Y[j])

斜率:-A[i]/B[i]

但是 -A[i]/B[i] 不具有單調性

所以不能用單調隊列維護斜率

可以用平衡樹維護,O(n * logn * logn)

更簡單的方法:CDQ分治

?

假設現在正在計算 dp[l]~dp[r],即solve(l,r)

對于每個j∈[l,r],[1,j-1]都是j的一種決策

令 mid=(l+r)/ 2

我們先計算出 dp[l]~dp[mid],然后用這些去更新 dp[mid+1]~dp[r]

假設我們現在已有了dp[l]~dp[mid]的上凸殼

那么如果保證 mid+1~r的斜率單調

就可以在線性時間內完成 dp[l]~dp[mid] 對 dp[mid+1]~dp[r]的更新

斜率單調可以在歸并排序之前的排序預處理中解決

僅剩的問題:如何得到dp[l]~dp[mid] 構成的上凸殼?

在每一層最后歸并的時候,我們用線形的時間使l~mid 的點 有序

即橫坐標為第一關鍵字,縱坐標為第二關鍵字 升序排列,

那么處理完l~mid之后,

會得到l~mid 所有的點 升序排列的結果

對于一些有序的點,用單調棧維護斜率遞減即可維護出上凸殼

然后利用這個上凸殼去更新mid+1~r 即可

復雜度為 O(nlogn)

?

#include<cmath> #include<cstdio> #include<algorithm> #include<iostream>using namespace std;#define N 100001const double eps=1e-7;struct node {double A,B,R;double X,Y;double K;int id;bool operator < (node p) const{/*if(fabs(X-p.X)>eps) return X<p.X;return Y<p.Y;*/return X<p.X;}}e[N],t[N]; double dp[N],ans;int st[N],top;bool down(int i,int j,int k) {return (e[j].X-e[i].X)*(e[k].Y-e[i].Y)-(e[k].X-e[i].X)*(e[j].Y-e[i].Y)<0; }void solve(int l,int r) {if(l==r){dp[l]=max(dp[l],dp[l-1]);e[l].Y=dp[l]/(e[l].A*e[l].R+e[l].B);e[l].X=e[l].Y*e[l].R;return;}int mid=l+r>>1;int opl=l,opr=mid+1;for(int i=l;i<=r;++i)if(e[i].id<=mid) t[opl++]=e[i];else t[opr++]=e[i];for(int i=l;i<=r;++i) e[i]=t[i];solve(l,mid);top=0;for(int i=l;i<=mid;++i){while(top>1 && !down(st[top-1],st[top],i)) top--;st[++top]=i;}int now=1;for(int i=mid+1;i<=r;++i){while(now<top && (e[st[now]].Y-e[st[now+1]].Y)<(e[st[now]].X-e[st[now+1]].X)*e[i].K) now++;dp[e[i].id]=max(dp[e[i].id],e[st[now]].X*e[i].A+e[st[now]].Y*e[i].B);}solve(mid+1,r);opl=l; opr=mid+1;for(int i=l;i<=r;++i) if(opl>mid) t[i]=e[opr++];else if(opr>r) t[i]=e[opl++];else if(e[opl]<e[opr]) t[i]=e[opl++];else t[i]=e[opr++];for(int i=l;i<=r;++i) e[i]=t[i]; } bool cmp(node p,node q) {return p.K>q.K; }int main() {int n;double m;scanf("%d%lf",&n,&dp[0]);for(int i=1;i<=n;++i) {scanf("%lf%lf%lf",&e[i].A,&e[i].B,&e[i].R);e[i].K=-e[i].A/e[i].B;e[i].id=i;}sort(e+1,e+n+1,cmp);solve(1,n);printf("%.3lf",dp[n]); }

?

1492: [NOI2007]貨幣兌換Cash

Time Limit:?5 Sec??Memory Limit:?64 MB
Submit:?5830??Solved:?2342
[Submit][Status][Discuss]

Description

小Y最近在一家金券交易所工作。該金券交易所只發行交易兩種金券:A紀念券(以下簡稱A券)和 B紀念券(以下 簡稱B券)。每個持有金券的顧客都有一個自己的帳戶。金券的數目可以是一個實數。每天隨著市場的起伏波動, 兩種金券都有自己當時的價值,即每一單位金券當天可以兌換的人民幣數目。我們記錄第 K 天中 A券 和 B券 的 價值分別為 AK 和 BK(元/單位金券)。為了方便顧客,金券交易所提供了一種非常方便的交易方式:比例交易法 。比例交易法分為兩個方面:(a)賣出金券:顧客提供一個 [0,100] 內的實數 OP 作為賣出比例,其意義為:將 OP% 的 A券和 OP% 的 B券 以當時的價值兌換為人民幣;(b)買入金券:顧客支付 IP 元人民幣,交易所將會兌 換給用戶總價值為 IP 的金券,并且,滿足提供給顧客的A券和B券的比例在第 K 天恰好為 RateK;例如,假定接 下來 3 天內的 Ak、Bk、RateK 的變化分別為: 假定在第一天時,用戶手中有 100元 人民幣但是沒有任何金券。用戶可以執行以下的操作: 注意到,同一天內可以進行多次操作。小Y是一個很有經濟頭腦的員工,通過較長時間的運作和行情測算,他已經 知道了未來N天內的A券和B券的價值以及Rate。他還希望能夠計算出來,如果開始時擁有S元錢,那么N天后最多能 夠獲得多少元錢。

?

Input

輸入第一行兩個正整數N、S,分別表示小Y能預知的天數以及初始時擁有的錢數。接下來N行,第K行三個實數AK、B K、RateK,意義如題目中所述。對于100%的測試數據,滿足:0<AK≤10;0<BK≤10;0<RateK≤100;MaxProfit≤1 0^9。 【提示】 1.輸入文件可能很大,請采用快速的讀入方式。 2.必然存在一種最優的買賣方案滿足: 每次買進操作使用完所有的人民幣; 每次賣出操作賣出所有的金券。

Output

只有一個實數MaxProfit,表示第N天的操作結束時能夠獲得的最大的金錢數目。答案保留3位小數。

Sample Input

3 100
1 1 1
1 2 2
2 2 3

Sample Output

225.000

HINT

?

?

轉載于:https://www.cnblogs.com/TheRoadToTheGold/p/8453384.html

總結

以上是生活随笔為你收集整理的bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。