[bzoj1855][Scoi2010]股票交易
阿新 • • 發佈:2018-04-07
void 股票行情 在那 交易所 inpu desc 整數 for logs
2 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1
f[i][j]=max(f[i][j],f[i-w-1][k+(k-j)*bp])
於是就這麽愉快的TLE了
顯然,n^3的復雜度是會被毒瘤出題人卡掉的,要不然怎麽對得起省選名號?
再看一下需要n^3復雜度的情況3和4,想想如何優化 方程:f[i][j]=max(f[i][j],f[i-w-1][(j-k)*ap])
由前面的分析可以知道,j,k,as滿足下面的關系: j-as<=k<=j
f[i][j]=max(f[i][j],f[i-w-1][k+k*ap])-j*ap
再轉化一下,其實就是在j-as到j這個區間內,找出最大值,發現了什麽?就是滑動窗口求最大值這種模板類的東西(放入隊列的元素即f[i-w-1][k+k*ap])
所以成功祭出單調隊列大法,化掉k這一層循環
方程:f[i][j]=max(f[i][j],f[i-w-1][k+k*ap]-j*ap)
同理可將第四種情況化為f[i][j]=max(f[i][j],f[i-w-1][k+k*bp]-j*bp)
其實三四種情況基本一樣,還有就是第四種情況需要倒序枚舉
代碼:
Description
最近lxhgww又迷上了投資股票,通過一段時間的觀察和學習,他總結出了股票行情的一些規律。 通過一段時間的觀察,lxhgww預測到了未來T天內某只股票的走勢,第i天的股票買入價為每股APi,第i天的股票賣出價為每股BPi(數據保證對於每個i,都有APi>=BPi),但是每天不能無限制地交易,於是股票交易所規定第i天的一次買入至多只能購買ASi股,一次賣出至多只能賣出BSi股。 另外,股票交易所還制定了兩個規定。為了避免大家瘋狂交易,股票交易所規定在兩次交易(某一天的買入或者賣出均算是一次交易)之間,至少要間隔W天,也就是說如果在第i天發生了交易,那麽從第i+1天到第i+W天,均不能發生交易。同時,為了避免壟斷,股票交易所還規定在任何時間,一個人的手裏的股票數不能超過MaxP。 在第1天之前,lxhgww手裏有一大筆錢(可以認為錢的數目無限),但是沒有任何股票,當然,T天以後,lxhgww想要賺到最多的錢,聰明的程序員們,你們能幫助他嗎?Input
輸入數據第一行包括3個整數,分別是T,MaxP,W。 接下來T行,第i行代表第i-1天的股票走勢,每行4個整數,分別表示APi,BPi,ASi,BSi。Output
輸出數據為一行,包括1個數字,表示lxhgww能賺到的最多的錢數。Sample Input
5 2 02 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1
Sample Output
3HINT
對於30%的數據,0 < =W 對於50%的數據,0 < =W 對於100%的數據,0 < =W
對於所有的數據,1 < =BPi < =APi < =1000,1 < =ASi,BSi < =MaxP
題解:
DP(狀態一大堆的那種毒瘤DP) ps:i表示第i天,j表示買j股股票 四種情況: 第一種,直接買 f[i][j]=-1*j*ap(理解成初始化?) 第二種,什麽都不做,f[i][j]=max(f[i-1][j],f[i][j]) 第三種,在之前基礎上買 分析一下,因為題目中說每次購買股票需要間隔w天,也就是說如果你第i天買了股票,那麽上一次購買一定是在第i-w-1天,設在那之前手上一共有k張股票,於是可以得出方程:f[i][j]=max(f[i][j],f[i-w-1][(j-k)*ap]) 第四種,賣出股票,與第三種類似,一樣設在這之前手中一共有k張股票,只需修改一下,就可以得到方程:
#include <cstdio> #include <cstring> #define ll int #define inf 1<<30 #define mt(x,y) memset(x,y,sizeof(x)) #define max(x,y) x>y?x:y #define min(x,y) x<y?x:y #define abs(x) x>0?x:-x inline void read(ll &x){ x=0;ll f=1;char c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-f;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} x*=f; } using namespace std; #define N 2010 ll f[N][N],q[N]; ll t,mp,w,ap,as,bp,bs,ans=0,l,r; int main(){ memset(f,128,sizeof(f)); read(t);read(mp);read(w); for(ll i=1;i<=t;i++){ read(ap);read(bp);read(as);read(bs); for(ll j=0;j<=as;j++)f[i][j]=-1*j*ap; for(ll j=0;j<=mp;j++)f[i][j]=max(f[i][j],f[i-1][j]); if(i<=w)continue; l=1,r=0; for(ll j=0;j<=mp;j++){ while(l<=r&&q[l]<j-as)l++; while(l<=r&&f[i-w-1][q[r]]+q[r]*ap<=f[i-w-1][j]+j*ap)r--; q[++r]=j; if(l<=r)f[i][j]=max(f[i][j],f[i-w-1][q[l]]+q[l]*ap-j*ap); }l=1;r=0; for(ll j=mp;j>=0;j--){ while(l<=r&&q[l]>j+bs)l++; while(l<=r&&f[i-w-1][q[r]]+q[r]*bp<=f[i-w-1][j]+j*bp)r--; q[++r]=j; if(l<=r)f[i][j]=max(f[i][j],f[i-w-1][q[l]]+q[l]*bp-j*bp); } } for(ll i=0;i<=mp;i++){ ans=max(ans,f[t][i]); } printf("%d\n",ans); return 0; }
轉載請註明出處:http://www.cnblogs.com/henry-1202/p/8733347.html
[bzoj1855][Scoi2010]股票交易