题解 CF1743C
题解 CF1743C
芝士 \(dp\) 题
设定 \(dp[i][0/1]\) 表示前 \(i\) 个盒子的最大值,以及第 \(i\) 个盒子的盖子是( \(1\) )否( \(0\) )移动
下面进行分类讨论即可
-
如果没有盖子,那就直接继承上一个的最大值
-
如果有盖子,那就考虑移动和不移动两种情况,不移动也是直接继承上一个的最大值
否则就讨论第 \(i-1\) 个是否有盖子,没有不需要移动第 \(i-1\) 个,否则就需要移动才能加上第 \(i\) 个
#include<cstdio>
#include<string.h>
using namespace std;
const int N=2e5+10;
int dp[N][2],a[N],vis[N];
int T,n;
int max(int x,int y){
return x>y?x:y;
}
int main(){
scanf("%d",&T);
while(T--){
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%1d",&vis[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(vis[i]){
dp[i][0]=a[i];
}
}
for(int i=2;i<=n;i++){
if(vis[i]){
dp[i][0]=max(dp[i-1][0]+a[i],dp[i-1][1]+a[i]);
// dp[i][0]+=max(dp[i-1][0],dp[i-1][1]);
if(!vis[i-1]){
dp[i][1]=dp[i-1][0]+a[i-1];
}else{
dp[i][1]=dp[i-1][1]+a[i-1];
}
}else{
dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
}
}
printf("%d\n",max(dp[n][0],dp[n][1]));
}
return 0;
}