您的位置:首页 > 产品设计 > UI/UE

UESTC 1186 Gray code - 简单数位dp

2016-02-17 22:36 483 查看
题目描述

题目大意:

给定一个长度为 n 的仅包含’0’、’1’、’?’ 的字符串,你需要给所有的问号决定填 0 还是 1。

填完之后,将这个串看成二进制数,转化成格雷码。

如果格雷码中第 i 个字符是 1,那么你将获得 ai 点分数。求可以得到的 分数的最大值。

1 ≤n≤ 200000,1 ≤ai ≤ 1000。

Source:2015 Multi-University Training Contest 7

From Claris

分析:

PS:二进制码转换为格雷码的方法为将二进制码右移一位然后与 原来的二进制码按位异或。

简单数位dp

设dp[i][0/1] :表示考虑前i位,第i位填0/1所得的最大分数和

如果第i位为’?’,有:

dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]);

dp[i][1]=max(dp[i-1][1],dp[i-1][0]+a[i]);

如果当前位已确定,看前一位是否确定,根据前一位的状态转移。

注意非法状态不能要!!

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 200000
#define INF 2000000000
typedef long long LL;

int n,a[MAXN+10];
LL dp[MAXN+10][2];
char s[MAXN+10];

int main()
{
int T;
scanf("%d",&T);
for(int k=1;k<=T;k++){
scanf("%s",s+1);
int n=strlen(s+1);
s[0]='0';
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(dp,0,sizeof dp);
dp[0][1]=-INF;
for(int i=1;i<=n;i++){
if(s[i]=='?'){
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]);
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+a[i]);
}
else{
if(s[i-1]!='?'){
if(s[i]!=s[i-1]){
dp[i][s[i]-'0']=dp[i-1][s[i-1]-'0']+a[i];
dp[i][1-(s[i]-'0')]=-INF;
}
else{
dp[i][s[i]-'0']=dp[i-1][s[i-1]-'0'];
dp[i][1-(s[i]-'0')]=-INF;
}
}
else{
dp[i][1-(s[i]-'0')]=-INF;
dp[i][s[i]-'0']=max(dp[i-1][s[i]-'0'],dp[i-1][1-(s[i]-'0')]+a[i]);
}
}
}
printf("Case #%d: %lld\n",k,max(dp
[0],dp
[1]));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: