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
格雷码:是由二进制当前位对前以为异或得到的;
eg:二进制 (0)10011
格雷码 11010 即:0^1=1; 1^0=1; 0^0=0; 0^1=1; 1^1=0;
所以:有 (0)x???y 和 (0)x??y <x,y=='0','1','?'>
当x,y不是'?'
当x==y的时候:如果xy之间的?是奇数个那么把x后面的值到y都加起来a[i],(x<i<=y);
那么如果是偶数个呢,那就把和减去min(a[i]),(x<i<=y);
eg: 0????0 那么我们应该让串为:010010 ----->对应格雷码:010111
a[i]= 5 4 2 1 3 6 所以sum=4+2+3+6=15;
当x!=y的时候:如果xy之间的?是偶数个那么把x后面的值到y都加起来a[i],(x<i<=y);
那么如果是奇数个呢,那就把和减去min(a[i]),(x<i<=y);
eg: 0???1 那么我们应该让串为:01101 ----->对应格雷码:01011
a[i]= 5 4 1 2 3 所以sum=4+2+3=9;
等于'?'相当于上述情况,你可以在首位加(0);
转载请注明出处:寻找&星空の孩子
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5375
#include <stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 200005 #define LL long long int t,len,a[N],ca=1; char str[N]; int main() { // freopen("a.txt","r",stdin); scanf("%d",&t); while(ca<=t) { scanf("%s",str+1); len=strlen(str+1); a[0]=0; for(int i=1;i<=len;i++) { scanf("%d",&a[i]); } int flag=0,s1,s2,sa=0; LL sum=0; str[0]='0'; char st='0',en; for(int i=1;i<=len;i++) { if(str[i]!='?') { en=str[i]; s2=a[i]; if(sa>0) { sum+=s2; if(sa&1 && st!=en) sum-=min(s1,s2); else if(sa%2==0 && st==en) sum-=min(s1,s2); } sa=0; st=str[i]; if(str[i-1]!='?' && str[i]^str[i-1]) sum+=a[i]; } else { sa++; sum+=a[i]; if(sa==1) s1=a[i]; else s1=min(s1,a[i]); } } printf("Case #%d: %lld\n",ca++,sum); } return 0; }
##1007. Gray code
格雷码 题解 标准格雷码的性质:二进制a1 a2 ... an,对应的格雷码为a1 (a1 xor a2) ... (an-1 xor an) 题目就可以转为O(n)的dp dp[i][j]表示二进制第i位为j时前i位对应最大分数.
当然dp就不要考虑这么多了:
#include <iostream> #include <stdio.h> #include <string.h> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <math.h> #include <bitset> #include <algorithm> #include <climits> using namespace std; #define ls 2*i #define rs 2*i+1 #define UP(i,x,y) for(i=x;i<=y;i++) #define DOWN(i,x,y) for(i=x;i>=y;i--) #define MEM(a,x) memset(a,x,sizeof(a)) #define W(a) while(a) #define gcd(a,b) __gcd(a,b) #define LL long long #define ULL unsigned long long #define N 200005 #define INF 0x3f3f3f3f #define EXP 1e-8 #define rank rank1 const int mod = 1000000007; int n; char str[N]; LL dp[N][2],a[N]; int main() { int i,j,k,cas = 1,t; scanf("%d",&t); while(t--) { scanf("%s",str+1); int len = strlen(str+1); for(i = 1; i<=len; i++) scanf("%d",&a[i]); MEM(dp,0); for(i = 1; i<=len; i++) { if(i==1) { if(str[i]=='?') { dp[i][0] = 0; dp[i][1] = a[i]; } else if(str[i]=='1') dp[i][1] = a[i]; else dp[i][0] = 0; } else { if(str[i]=='?') { if(str[i-1]=='1') { dp[i][1]=dp[i-1][1]; dp[i][0]=dp[i-1][1]+a[i]; } else if(str[i-1]=='0') { dp[i][1]=dp[i-1][0]+a[i]; dp[i][0]=dp[i-1][0]; } else { dp[i][1]=max(dp[i-1][1],dp[i-1][0]+a[i]); dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]); } } else if(str[i]=='1') { if(str[i-1]=='1') dp[i][1]=dp[i-1][1]; else if(str[i-1]=='0') dp[i][1]=dp[i-1][0]+a[i]; else dp[i][1]=max(dp[i-1][1],dp[i-1][0]+a[i]); } else { if(str[i-1]=='1') dp[i][0]=dp[i-1][1]+a[i]; else if(str[i-1]=='0') dp[i][0]=dp[i-1][0]; else dp[i][0]=max(dp[i-1][1]+a[i],dp[i-1][0]); } } } printf("Case #%d: %I64d\n",cas++,max(dp[len][0],dp[len][1])); } return 0; }