Gray code
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 384 Accepted Submission(s): 216
![hdu5375Gray code(dp) - NatureRan - NatureRan hdu5375Gray code(dp) - NatureRan - NatureRan](https://i-blog.csdnimg.cn/blog_migrate/c883933cbffdc1f310152072c114cbe2.jpeg)
Now , you are given a binary number of length n including ‘0’ , ’1’ and ‘?’(? means that you can use either 0 or 1 to fill this position) and n integers(a1,a2,….,an) . A certain binary number corresponds to a gray code only. If the ith bit of this gray code is 1,you can get the point ai.
Can you tell me how many points you can get at most?
For instance, the binary number “00?0” may be “0000” or “0010”,and the corresponding gray code are “0000” or “0011”.You can choose “0000” getting nothing or “0011” getting the point a3 and a4.
Each test case begins with string with ‘0’,’1’ and ‘?’.
The next line contains n (1<=n<=200000) integers (n is the length of the string).
a1 a2 a3 … an (1<=ai<=1000)
2 00?0 1 2 4 8 ???? 1 2 4 8
Case #1: 12 Case #2: 15Hinthttps://en.wikipedia.org/wiki/Gray_code http://baike.baidu.com/view/358724.htm
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int n,len;
char str[200005];
int arr[200005];
long long dp[200005][2];
int main(int argc, char *argv[])
{
int i,x;
scanf("%d",&n);
for(x=1;x<=n;x++){
scanf("%s",str);
len=strlen(str);
for(i=0;i<len;i++) scanf("%d",&arr[i]);
if(str[0]=='0') dp[0][0]=dp[0][1]=0;
if(str[0]=='1') dp[0][0]=dp[0][1]=arr[0];
if(str[0]=='?') dp[0][0]=0;dp[0][1]=arr[0];
for(i=1;i<len;i++){
if(str[i]=='?'){
if(str[i-1]=='?'){
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+arr[i]);
dp[i][1]=max(dp[i-1][0]+arr[i],dp[i-1][1]);
}
if(str[i-1]=='0'){
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][0]+arr[i];
}
if(str[i-1]=='1'){
dp[i][0]=dp[i-1][1]+arr[i];
dp[i][1]=dp[i-1][1];
}
}
else if(str[i]=='0'){
if(str[i-1]=='?'){
dp[i][0]=dp[i][1]=max(dp[i-1][0],dp[i-1][1]+arr[i]);
}
if(str[i-1]=='0'){
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][0];
}
if(str[i-1]=='1'){
dp[i][0]=dp[i-1][1]+arr[i];
dp[i][1]=dp[i-1][1]+arr[i];
}
}
else if(str[i]=='1'){
if(str[i-1]=='?'){
dp[i][0]=dp[i][1]=max(dp[i-1][1],dp[i-1][0]+arr[i]);
}
if(str[i-1]=='0'){
dp[i][0]=dp[i-1][0]+arr[i];
dp[i][1]=dp[i-1][0]+arr[i];
}
if(str[i-1]=='1'){
dp[i][0]=dp[i-1][1];
dp[i][1]=dp[i-1][1];
}
}
}
printf("Case #%d: %lld\n",x,max(dp[len-1][0],dp[len-1][1]));
}
return 0;
}