2015 Multi-University Training Contest 7
Gray code
题意:将一个n位二进制数(二进制数中有些位数上的数子是未知的,表示成‘?’,也就是说转换成的格雷码有多种可能)转换为格雷码gray[n],同时给出一个n个整数a[n],求a[i]*gray[i]和的最大值。
思路:用动态规划做,二进制数a0 a1 a2 ....... an 转换成格雷码位 a0 (a0^a1) (a1^a2) ...... (an-1 ^ an)。
#include<stdio.h>
#include<string.h> #define maxn 200005 char binary[maxn]; int a[maxn],gray[maxn]; int cas,length,i,j; long long dp[maxn][2]; /*dp[i][j]表示第i位为j时最大的值*/ void init() { int i,j; for(i = 0;i < maxn;i ++) dp[i][0] = dp[i][1] = -1; } long long Get_Gray() { int i,j; long long t1,t0; if(binary[0] =='?') { dp[0][0] = 0; dp[0][1] = a[0]; } else if(binary[0]!='?') { gray[0] = binary[0] - '0'; dp[0][gray[0]] = gray[0] * a[0]; /*printf("%d ",dp[0][0]);*/ } for(i = 1;i < length;i ++) { t0 = t1 = -1; if(binary[i] == '?') { if(dp[i-1][ 0] >= 0){ t0 = (0^0) * a[i] + dp[i-1][0]; } if(dp[i-1][1] >= 0){ t1 = (1^0) * a[i] + dp[i-1][1]; } dp[i][0] = t0 > t1?t0:t1; if(dp[i-1][0] >= 0){ t0 = (0^1) * a[i] + dp[i-1][0]; } if(dp[i-1][1] >= 0){ t1 = (1^1) * a[i] + dp[i-1][1]; } dp[i][1] = t0 > t1?t0:t1; } else if(binary[i] == '0') { if(dp[i-1][0] >= 0){ t0 = (0^0) * a[i] + dp[i-1][0]; } if(dp[i-1][1] >= 0){ t1 = (1^0) * a[i] + dp[i-1][1]; } dp[i][0] = t0 > t1?t0:t1; } else if(binary[i] == '1') { if(dp[i-1][0] >= 0){ t0 = (0^1) * a[i] + dp[i-1][0]; } if(dp[i-1][1] >= 0){ t1 = (1^1) * a[i] + dp[i-1][1]; } dp[i][1] = t0 > t1?t0:t1; } } return (dp[length-1][1]>dp[length-1][0]?dp[length-1][1]:dp[length-1][0]); } int main(void) { long long ans,t = 1; scanf("%d",&cas); getchar(); while(cas --) { init(); scanf("%s",binary); length = strlen(binary); for(i = 0;i < length;i ++) scanf("%d",&a[i]); getchar(); ans = Get_Gray(); printf("Case #%lld: %lld ",t ++,ans); } return 0; }
小结:刚开始做的时候数组开小了,提交的时候错误是 Time Limit Exceed 。