hdu3401 單調佇列優化dp

2022-05-23 18:24:10 字數 1941 閱讀 5509

第乙個單調佇列優化dp

寫了半天,最後初始化搞錯了還一直wa。。

題目大意:

**,總共 t 天,每天可以**na[i]股,賣出nb[i]股,價錢分別為pa[i]和pb[i],最大同時擁有p股

且一次交易後至少要間隔w天才能再次交易,初始有0股,本金無限,求最大收益

題解:dp[i][j]表示第 i 天,有 j 股的最大收益

狀態轉移 dp[i][j]=max

複雜度 為 t*t*p*p

首先我們可以看出 dp[i][j]>=dp[i-1][j](不買不賣轉移)

所以可以將 r 確定為 i-w-1,複雜度變為t*p*p 還是很大

然後對於買,移項有

dp[i][j]+j*pa[i]=dp[r][k]+k*pa[i]。右邊與 j無關, 可見我們只需要對每乙個 i 維護乙個關於k的單調佇列,就可以在 p時間內求出所有的dp[i][j]

複雜度降為 t*p 可以接受了

最後注意下邊界條件:

1到w+1的都是從初始條件下轉移的

**:

#include #include 

#include

#include

#include

#include

using

namespace

std;

#define maxn 2000

#define inf 200000000

int na[maxn+10],nb[maxn+10],pa[maxn+10],pb[maxn+10

];int dp[maxn+10][maxn+10

];int

t,p,w;

typedef

struct

node

node;

typedef

struct

dqueue

void

clear()

node front()

void

pop()

void

push(node x)

if(x.val>q[l].val)

for(int i=r;i>l;i--)

}q[r++]=x;

}}dqueue;

dqueue qa,qb;

int buy(int now,int

n)

else

break

; }

return

tmp.val;

}int sale(int now,int

n)

else

break

; }

return

tmp.val;

}void

dp()

}node no;

for(int i=1;i<=w+1;i++)

for(int j=0;j<=p;j++)

}for(int i=w+2;i<=t;i++)

for(int j=0;j<=p;j++)

dp[i][j]=max(dp[i][j],dp[i-1][j]); //

不買int tmp=buy(i,j);

dp[i][j]=max(dp[i][j],tmp-j*pa[i]); //

買 tmp=sale(i,j);

dp[i][j]=max(dp[i][j],tmp-j*pb[i]); //賣}

}}int

main()

dp();

int ans=0

;

for(int i=0;i<=p;i++)

printf(

"%d\n

",ans);

}return0;

}

hdu 3401 單調佇列優化動態規劃

思路 動態方程很容易想到dp i j max dp i j dp i w 1 j k k ap i dp i w 1 j k k bp i dp i j 表示第i天擁有j個石頭的最大價值。其實每次求得都是最有策略,所有dp i w 1 表示的就是i w 1以前的最優,故不同往前遍歷。那麼主要需要優化...

HDU 3401 Trade 單調佇列優化dp

題目大意 現在要你去 給你每天的開盤價值,每股 價值為ap,賣出價值為bp,每天最多買as股,最多賣出bs股,並且要求兩次買賣必須間隔w天,問你在t天內如何進行 操作從而獲得最大收益。解題思路 先吐槽一下,會單調佇列但不會dp不行,會dp但不會單調佇列也不行!開始dp動態轉移方程倒是寫對了,然後算算...

HDU3401 Trade 單調佇列優化dp

分析可以設定二維的dp狀態i天有j塊錢的最大收益 對w 1天之前的每天進行初始化,因為在這個時候只能買,也可以不買,但是這個不買在後面進行集體操作 之後就有3種情況,一種是買,一種是不操作,一種賣出 並且只有當滿足條件的時候才能進行買賣,那麼這個優化方法就明顯了,不買的情況就是等於前一天這個錢的大小...