[关闭]
@xiaoziyao 2020-10-20T11:36:12.000000Z 字数 855 阅读 799

CF1238E Keyboard Purchase解题报告

解题报告


CF1238E Keyboard Purchase解题报告:

更好的阅读体验

题意

分析

状压dp。

看到这么小的,我们就可以大概猜出要压这个,于是套路的设计状态:为设计的键盘(不需要设计完)用到的所有字母压缩起来是的最小缓慢度。

但是有一个问题,对于这个状态,我们不能知道它字母的顺序,所以并不能统计答案。

我们要设计一种无后效性的dp:每一次装一个字母就直接统计出来它的所有贡献(费用提前思想)。

考虑装一个字母的贡献:会让所有相邻且一个装了一个没装的字母对距离加一,这样我们就可以快速地统计出来答案了。

相邻的状态数,很容易统计出来,然后就是套路的状压dp了。

代码

代码非常简短,记得开

  1. for(int i=1;i<n;i++)
  2. cnt[s[i]-96][s[i+1]-96]++,cnt[s[i+1]-96][s[i]-96]++;
  3. st=(1<<m)-1;
  4. f[0]=0;
  5. for(int i=1;i<=st;i++){
  6. int sum=0;
  7. f[i]=inf;
  8. for(int j=1;j<=m;j++)
  9. for(int k=j+1;k<=m;k++)//不统计重复
  10. if(((i>>(j-1))&1)^((i>>(k-1))&1))//j在键盘上或k在键盘上
  11. sum+=cnt[j][k];
  12. for(int j=1;j<=m;j++)
  13. if((i>>(j-1)&1))
  14. f[i]=min(f[i],f[i^(1<<(j-1))]+sum);
  15. }
  16. printf("%lld\n",f[st]);
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注