题目地址:HDU 5375
题意:给你一个二进制串,带’?’的位置可以由你来决定填’1’还是’0’,补充完整之后转换成格雷码表示,每一个位置都有一个权值a[i],只有格雷码为’1’的位可以加上权值,问你最终权值之和最大为多少。
思路:首先要明白二进制码和格雷码是如何转换的:
dp[i][0]表示第i位为0的时候的最大值,dp[i][1]表示第i位为1的时候的最大值。对于第i位的最大值由dp[i-1][0],dp[i-1][1]和当前权值a[i]得到。当前的位的二进制码有0,1,?三种情况,所以就分这三种情况讨论一下。
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef __int64 LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
const double esp=1e-7;
const int Maxn=200010;
char str[Maxn];
int a[Maxn];
int dp[Maxn][2];
int main()
{
int T,i,j;
int Max;
int icase=1;
scanf("%d",&T);
while(T--){
scanf("%s",str);
int len=strlen(str);
memset(dp,-1,sizeof(dp));
for(i=0;i<len;i++)
scanf("%d",&a[i]);
if(str[0]==‘?‘){
dp[0][0]=0;
dp[0][1]=a[0];
}
else if(str[0]==‘0‘){
dp[0][0]=0;
}
else if(str[0]==‘1‘){
dp[0][1]=a[0];
}
for(i=1;i<len;i++){
if(str[i]==‘?‘){
Max=-inf;
if(dp[i-1][0]!=-1)
Max=max(Max,dp[i-1][0]);
if(dp[i-1][1]!=-1)
Max=max(Max,dp[i-1][1]+a[i]);
dp[i][0]=Max;
Max=-inf;
if(dp[i-1][0]!=-1)
Max=max(Max,dp[i-1][0]+a[i]);
if(dp[i-1][1]!=-1)
Max=max(Max,dp[i-1][1]);
dp[i][1]=Max;
}
else if(str[i]==‘0‘){
Max=-inf;
if(dp[i-1][0]!=-1)
Max=max(Max,dp[i-1][0]);
if(dp[i-1][1]!=-1)
Max=max(Max,dp[i-1][1]+a[i]);
dp[i][0]=Max;
}
else if(str[i]==‘1‘){
Max=-inf;
if(dp[i-1][0]!=-1)
Max=max(Max,dp[i-1][0]+a[i]);
if(dp[i-1][1]!=-1)
Max=max(Max,dp[i-1][1]);
dp[i][1]=Max;
}
}
printf("Case #%d: %d\n",icase++,max(dp[len-1][0],dp[len-1][1]));
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-08 21:23:45