玄学的dp问题
查看原帖
玄学的dp问题
109220
Farkas_W楼主2021/3/18 15:10

这是 ACAC 代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#define re register int
#define il inline
using namespace std;
il int read()
{
  int x=0,f=1;char ch=getchar();
  while(!isdigit(ch)&&ch!='-')ch=getchar();
  if(ch=='-')f=-1,ch=getchar();
  while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
  return x*f;
}
il void print(int x)
{
  if(x<0)putchar('-'),x=-x;
  if(x/10)print(x/10);
  putchar(x%10+'0');
}
int n,k,ch[400][3],v[400],f[1002][400],fail[400],cnt,ans;
char s[20];
il void insert()
{
	scanf("%s",s+1);int len=strlen(s+1),u=0;
	for(re i=1;i<=len;i++)
	{
		int x=s[i]-'A';
		if(!ch[u][x])ch[u][x]=++cnt;
		u=ch[u][x];
	}
	v[u]++;
}
il void get_fail()
{
	queue<int>q;
	for(re i=0;i<3;i++)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(re i=0;i<3;i++)
		{
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
		}
		v[u]+=v[fail[u]];
	}
}
il void dp()
{
	memset(f,128,sizeof(f)); //here
	for(re i=0;i<=k;i++)f[i][0]=0;
	for(re i=1;i<=k;i++)
	for(re j=0;j<=cnt;j++)
	for(re l=0;l<3;l++)
	f[i][ch[j][l]]=max(f[i][ch[j][l]],f[i-1][j]+v[ch[j][l]]);
}
signed main()
{
	n=read();k=read();
	for(re i=1;i<=n;i++)insert();
	get_fail();dp();
	for(re i=1;i<=cnt;i++)ans=max(ans,f[k][i]);
	printf("%d",ans);
	return 0;
}

其中 memsetmemset 是把 ff 数组初始化为一个负值(极小值)

memset(f,128,sizeof(f));

但是把 128128 变成 1-1 就只有 2020 分,按理说 dpdp 初始值只要是负数就可以了,为什么会错呢?

20分记录 100分记录

2021/3/18 15:10
加载中...