应该算是水题,然而比赛的时候就是敲不出来,以为某段?之间的最小值只能在两端取到,结果一直wa。其实,一段内都有可能是最小值,所以去掉这个最小值去掉就可以了。代码写的有点冗长。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <sstream>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long LL;
const double pi=4.0*atan(1.0);
const int MAXN=200005;
const int INF=20000;
char s[MAXN];
int a[MAXN];
int qianzui[MAXN];//前缀和
//奇偶指?个数
/* 0偶数1 */
/* 1偶数0 */
/* 0奇数0 */
/* 1奇数1 */
//以上四种一定能使所对应的值全部取到
//其余情况必须舍去一个最小值
int main()
{
int i,j,k;
int cas=1;
int temp,sum,ans,sign;
int slen,len;
int T;
//freopen("1007.in","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d",&T)!=EOF)
{
for(cas=1;cas<=T;cas++)
{
//最前面加个'0',去掉了 ???数字 的情况
s[0]='0';
scanf("%s",s+1);
slen=strlen(s);
a[0]=0;
qianzui[0]=0;
sum=0;
for(i=1;i<slen;i++)
{
scanf("%d",a+i);
qianzui[i]=qianzui[i-1]+a[i];
}
i=0;
int left,right;
ans=0;
int mm;
while(i<slen)
{
sign=0;
mm=INF;
//找第一个? 并记录下标
for(;i<slen;i++)
{
if(s[i]=='?')
{
left=i;
sign=1;
break;
}
}
if(sign==0)//如果sign==0,那么意味着剩下的全是数字
break;
for(;i<slen;i++)
{
if(s[i]!='?')
{
mm=min(a[i],mm);
right=i;
break;
}
else
{
mm=min(a[i],mm);
}
}
if(i==slen)//此时代表 数字???...?
{
//一定都能取到
ans+=qianzui[slen-1]-qianzui[left-1];
}
else
{
//left,right一定在
right--;
len=right-left+1;
if(s[left-1]=='0'&&s[right+1]=='0'||(s[left-1]=='1'&&s[right+1]=='1'))
{
if(len%2==1)
{
ans+=qianzui[right+1]-qianzui[left-1];
}
else
{
ans+=qianzui[right+1]-qianzui[left-1];
ans-=mm;
}
}
else
{
if(len%2==0)
{
ans+=qianzui[right+1]-qianzui[left-1];
}
else
{
ans+=qianzui[right+1]-qianzui[left-1];
ans-=mm;
}
}
}
}
//算上确定的值
for(i=1;i<slen;i++)
{
if(s[i-1]!='?'&&s[i]!='?')
{
int t1=s[i-1]-'0';
int t2=s[i]-'0';
ans+=(t1^t2)*a[i];
}
}
printf("Case #%d: %d\n",cas,ans);
}
}
return 0;
}
早上起来写dp,确实dp更简单,但是自己写得和别人的怎么差距那么大。还有好长一条路要走!
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <sstream>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long LL;
const double pi=4.0*atan(1.0);
const int MAXN=200005;
char s[MAXN];
int a[MAXN];
int dp[MAXN][3];
int main()
{
int i,j,k;
int cas=1;
int n,t;
//freopen("1007.in","r",stdin);
//freopen("out.txt","w",stdout);
int ans,sum;
int T;
while(scanf("%d",&T)!=EOF)
{
int cas=1;
while(T--)
{
s[0]='0';
scanf("%s",s+1);
int len=strlen(s);
for(i=1;i<len;i++)
scanf("%d",a+i);
memset(dp,0,sizeof(dp));
if(s[1]=='0')
dp[1][1]=dp[1][0]=0;
else if(s[1]=='1')
{
dp[1][1]=a[1];
dp[1][0]=0;
}
else
{
dp[1][1]=a[1];
dp[1][0]=0;
}
for(i=2;i<len;i++)
{
if(s[i]=='0')
{
if(s[i-1]=='0')
dp[i][0]=dp[i-1][0];
else if(s[i-1]=='1')
dp[i][0]=dp[i-1][1]+a[i];
else
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]);
}
else if(s[i]=='1')
{
if(s[i-1]=='0')
dp[i][1]=dp[i-1][0]+a[i];
else if(s[i-1]=='1')
dp[i][1]=dp[i-1][1];
else
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+a[i]);
}
else
{
if(s[i-1]=='0')
{
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][0]+a[i];
}
else if(s[i-1]=='1')
{
dp[i][0]=dp[i-1][1]+a[i];
dp[i][1]=dp[i-1][1];
}
else
{
dp[i][0]=max(dp[i-1][1]+a[i],dp[i-1][0]);
dp[i][1]=max(dp[i-1][0]+a[i],dp[i-1][1]);;
}
}
}
if(s[len-1]=='0')
printf("Case #%d: %d\n",cas++,dp[len-1][0]);
else if(s[len-1]=='1')
printf("Case #%d: %d\n",cas++,dp[len-1][1]);
else
printf("Case #%d: %d\n",cas++,max(dp[len-1][1],dp[len-1][0]));
}
}
return 0;
}