求助线性dp
查看原帖
求助线性dp
366746
烛木楼主2020/11/14 11:23
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
#define int long long
const int MAXN=2*150000+20;
int t,a,b,bef,cnt,tmp,imp[MAXN],st[MAXN],tim[MAXN],he[MAXN],dp[MAXN];
char s[MAXN];
bool j=1;
signed main()
{
	scanf("%lld",&t);
	while(t--)
	{
		tmp=bef=cnt=0;
		j=1;
		memset(imp,0,sizeof(imp));
		scanf("%lld%lld%s",&a,&b,s);
		int len=strlen(s);
		for(int i=0;i<len;i++) imp[i+1]=s[i]-'0';
		for(int i=1;i<=len;i++) dp[i]=1e12;
		int e=1;
		for(e=1;e<=len;e++)
		{
			if(imp[e]&&!tmp) he[e]=e,tmp=e,tim[e]=cnt;
			else if(!imp[e]&&tmp) break;
			else if(!imp[e]) ++cnt;
			else tim[e]=cnt;
		}
		for(e;e<=len;e++)//j==1意为前一位位于1链,反之则位于0链
		{
			if(j)
			{
				if(!imp[e])
				{
					j=0;
					bef=tmp;
					cnt=1;
				}
				else st[e]=bef,tim[e]=cnt,he[e]=tmp;
			}
			else
			{
				if(imp[e]) tmp=e,j=1,st[e]=bef,tim[e]=cnt,he[e]=tmp;
				else ++cnt;
			}
		}
		for(int i=1;i<=len;i++)
		{
			if(!imp[i]) dp[i]=min;
			else dp[i]=min(dp[st[i]-1]+tim[i]*b+a,dp[he[i]-1]+a);
		}
		printf("%lld\n",dp[len]);
	}
	return 0;
}
2020/11/14 11:23
加载中...