题解:AT_abc403_f [ABC403F] Shortest One Formula
打题时被自己唐死了。
首先拿到题感觉似乎不太可做,但看到
首先肯定要记忆化。
我们定义
bz[1]="1";
bz[11]="11";
bz[111]="111";
bz[1111]="1111";
string dfs(int x)
{
if(bz[x]!="\0") return bz[x];
if(f[x]!="\0") return f[x];
string res="\0";
for(int i=1;i<x;i++) res=cmp(res,dfs(i)+'+'+dfs(x-i));
for(int i=2;i*i<=x;i++)
if(x%i==0)
res=cmp(res,'('+dfs(i)+')'+'*'+'('+dfs(x/i)+')');
return f[x]=res;
}
然后就发现 WA 了。
想想为什么?
我们发现有一个 bug 就是在乘的时候我们加了两个括号!这就导致加了两个括号后长度加了
比如:
987=11+(1+1)*(1+1+1+1)*(11+111)=11+(1+1+1+1)*(11+11+111+111)
它们的区别就是对
244=(1+1)*(11+111)=11+11+111+111
对
那该怎么办?我们只用加一维:
inline string dfs(int x,bool pos)
{
if(bz[x]!="\0") return bz[x];
if(f[x][pos]!="\0") return f[x][pos];
string res="\0";
if(pos)
{
for(int i=1;i<x;i++) res=cmp(res,'('+dfs(i,0)+'+'+dfs(x-i,0)+')');
}
else
{
for(int i=1;i<x;i++) res=cmp(res,dfs(i,0)+'+'+dfs(x-i,0));
}
for(int i=2;i*i<=x;i++)
if(x%i==0)
res=cmp(res,dfs(i,1)+'*'+dfs(x/i,1));
return f[x][pos]=res;
}
时间应该是