题意:给出一个二进制数,其中有些位的数字不确定,对于所有对应的格雷码,与一个序列a对应,第i位数字为1时得分a[i],求最大的得分。
解法:一个二进制数x对应的格雷码为x ^ (x >> 1),题解说是个dp……但其实就四种情况……判一下就好了
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; string s; LL a[200005]; int main() { int T, cse; while(~scanf("%d", &T)) { cse = 1; while(T--) { cin >> s; int n = s.size(); string s1 = '0' + s; s1.erase(s1.end() - 1); for(int i = 0; i < n; i++) scanf("%lld", &a[i]); char st = '0'; LL ans = 0; for(int i = 0; i < n; i++) { if(s[i] != '?') { if(s[i] != s1[i]) ans += a[i]; st = s[i]; } else { int cnt = 0; LL sum = 0, minn = a[i]; while(i < n && s[i] == '?') { cnt++; sum += a[i]; minn = min(minn, a[i]); i++; } char ed; if(i < n) { ed = s[i]; sum += a[i]; minn = min(minn, a[i]); } else { ans += sum; break; } if(st == ed) { if(cnt & 1) ans += sum; else ans += sum - minn; } else { if(cnt & 1) ans += sum - minn; else ans += sum; } st = s[i]; } } printf("Case #%d: %lld ", cse++, ans); } } return 0; }