K-Box_2023牛客暑期多校训练营2 (nowcoder.com)
设j=0,1,2 分别为向左,不动,向右的情况。f[i][j]为第i个盖子下所能获取的最大值。
其中有条件 pos[i]+j-1>pos[i-1]+j'-1。
其余见代码注释。
#include <bits/stdc++.h>
using namespace std;
#define go(i, a, b) for (int i = a; i <= b; ++i)
#define com(i, a, b) for (int i = a; i >= b; --i)
#define mem(a, b) memset(a, b, sizeof(a))
#define int long long
typedef pair<int,int> pii;
const int maxn=1e6+5;
int a[maxn];
int dp[maxn][3];
signed main()
{
mem(dp,0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
dp[0][0]=dp[0][1]=dp[0][2]=0;
int ans=0;
vector<int> lid;
lid.push_back(-10);
for(int i=1;i<=n;i++)
{
int fl;
cin>>fl;
if(fl)
{
lid.push_back(i);//记录每个盖子位置在lid中
}
}
int m=lid.size()-1;
for(int i=1;i<=m;i++)//遍历每个盖子
{
// cout<<"i="<<i<<endl;
for(int j=0;j<=2;j++)//遍历向左不动向右情况
{
//cout<<"up"<<lid[i]-lid[i-1]+j<<endl;
for(int k=0;k<lid[i]-lid[i-1]+j&&k<=2;k++)//限制上一个盖子的情况选择
{
//cout<<"j="<<j<<"k="<<k<<endl;
dp[i][j]=max(dp[i][j],dp[i-1][k]+a[lid[i]+j-1]);
//cout<<dp[i][j]<<endl;
}
}
}
ans=max(dp[m][0],max(dp[m][1],dp[m][2]));
cout<<ans<<endl;
}