题目
HDU5375
将带有问号的二进制数字转换为权值最大的Gray code。
O(N)的DP。
思路
代码
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int mx = 200005;
int a[mx],dp[mx][2],cas;
char chr[mx];
int main(){
// freopen("t.in","r",stdin);
// freopen("t.out","w",stdout);
int T,l;
scanf("%d",&T);
while(T--){
scanf("%s",chr);
l=strlen(chr);
for(int i=0;i<l;i++){
scanf("%d",&a[i]);
}
memset(dp,-1,sizeof(dp));
if(chr[0]=='0')dp[0][0]=0;
if(chr[0]=='1')dp[0][1]=a[0];
if(chr[0]=='?') {
dp[0][0]=0;
dp[0][1]=a[0];
}
for(int i=1;i<l;i++){
if(chr[i-1]=='?'){
if(chr[i]=='?'){
dp[i][0]=max(dp[i][0],max(dp[i-1][0],dp[i-1][1]+a[i]));
dp[i][1]=max(dp[i][1],max(dp[i-1][0]+a[i],dp[i-1][1]));
}
if(chr[i]=='1'){
dp[i][1]=max(dp[i][1],max(dp[i-1][0]+a[i],dp[i-1][1]));
}
if(chr[i]=='0'){
dp[i][0]=max(dp[i][0],max(dp[i-1][0],dp[i-1][1]+a[i]));
}
}
if(chr[i-1]=='0'){
if(chr[i]=='?'){
dp[i][0]=max(dp[i][0],dp[i-1][0]);
dp[i][1]=max(dp[i][1],dp[i-1][0]+a[i]);
}
if(chr[i]=='1'){
dp[i][1]=max(dp[i][1],dp[i-1][0]+a[i]);
}
if(chr[i]=='0'){
dp[i][0]=max(dp[i][0],dp[i-1][0]);
}
}
if(chr[i-1]=='1'){
if(chr[i]=='?'){
dp[i][0]=max(dp[i][0],dp[i-1][1]+a[i]);
dp[i][1]=max(dp[i][1],dp[i-1][1]);
}
if(chr[i]=='1'){
dp[i][1]=max(dp[i][1],dp[i-1][1]);
}
if(chr[i]=='0'){
dp[i][0]=max(dp[i][0],dp[i-1][1]+a[i]);
}
}
}
int ans=max(dp[l-1][0],dp[l-1][1]);
printf("Case #%d: %d\n",++cas,ans);
}
return 0;
}