題名:
長さNの配列が与えられた場合、配列のi番目の数値は、i日目の特定の株式の価格を表します。
最大利益を計算するアルゴリズムを設計します。次の制約の下で、できるだけ多くのトランザクションを完了することができます(株式を複数回売買する)。
同時に複数の取引に参加することはできません(再度購入する前に前の株式を売却する必要があります)。
株式を売却した後、翌日には購入できません(つまり、凍結期間は1日です)。
回答:
凍結期間が考慮されない場合、
最初のi株のみが考慮されることを示すようにdp [i] [0]を設定し、株なしの現在の最大リターン
dp [i] [1]は、最初のi株のみを示すことを示しますみなされ、株式の現在の最大のリターンされている
今、凍結期間を考慮して、我々は唯一の最初のi銘柄が考慮されていることを示すために[i]の[2]をDP設定し、現在は凍結期間中の最大リターンすることができます。後は
、すべての条件(状態)が設定され
たら、状態遷移式の作成を開始します。現在、在庫はありません。前日に在庫が転送されなかった場合もあれば、凍結期間の前日に在庫が転送された場合もあります。
在庫が買った前に、現在の株式市場は、日を転送してもよいし、株価は前日に移された。
株式は売却された前の凍結期間は一日である。からの転送
最大値を取るために、最後の三つの状態
コード:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
}
const int maxn=1e5+9;
int a[maxn],dp[maxn][3];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
memset(dp,-0x3f,sizeof dp);
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
dp[i][0]=max(dp[i-1][0],dp[i-1][2]);
dp[i][1]=max(dp[i-1][0]-a[i],dp[i-1][1]) ;
dp[i][2]=max(dp[i-1][2],dp[i-1][1]+a[i]) ;
}
cout<<max(dp[n][0],max(dp[n][1],dp[n][2]))<<endl;
return 0;
}
/*
dp[i][0]没有股票
dp[i][1]有股票
dp[i][2]处于冷冻期
dp[i][0]=max(dp[i-1][0],dp[i-1][2])
dp[i][1]=max(dp[i-1][0]-a[i],dp[i-1][1])
dp[i][2]=max(dp[i-1][2],dp[i-1][1]+a[i])
*/