题意:

  给一个长度为n的字符串,定义$k=\floor{log_2 n}$

  一共k轮操作,第i次操作要删除当前字符串恰好长度为$2^{i-1}$的子串

  问最后剩余的字符串字典序最小是多少?

分析:

  首先很容易得到一个性质,那就是删除的那些串是可以不交叉的
  很容易想到一个很简单的dp

  dp[i][j]表示考虑原串的前i位,删除状态为j的情况下字典序最小的字符串(注意dp里面保存的是个字符串)

  那么很明显就是个O(n^3logn)的dp,无法通过

  dp里是一个字符串这个东西是很浪费时间而且很不优美的

  根据题解的做法,重新设计状态

  dp[i][j]表示已经确定了最终字符串的前i位,目前删除情况为j的情况下,字典序最小的字符串

  这样设计状态我们会发现一个性质,那就是如果dp[i][j]<dp[i][k],那么dp[i][k]就不起作用了

  所以dp数组可以用bool值来表示该状态是否为当前最小的字符串

  更新状态的话,根据确定位数i和删除位数j就知道那些"1"对应字符串的下一位是多少了,更新新的最小字符串

  然后我们要考虑当前阶段给后面要删除几个数,这里即使要求满足若一个状态的某个子集是真,那么它就是真

  这用一个高维前缀和解决即可

 #include<bits/stdc++.h>
using namespace std;
const int maxn=;
char s[maxn+];
bool dp[maxn+][maxn+];
int n,l,m;
string ans;
int main()
{
scanf("%s",s);
n=strlen(s);
l=;
while((<<(l+))<=n) ++l;
m=<<l;
for(int j=;j<m;++j)
dp[][j]=;
for(int i=;i<=n-m+;++i)
{
for(int j=;j<m;++j) dp[i][j]=dp[i-][j];
char mi='z';
for(int j=;j<m;++j)
if(dp[i-][j]) mi=min(mi,s[i-+j]);
for(int j=;j<m;++j)
if(dp[i][j]&&s[i-+j]!=mi) dp[i][j]=; for(int j=;j<m;++j)
for(int k=;k<l;++k)
if(j&(<<k)) dp[i][j]|=dp[i][j^(<<k)];
ans=ans+mi; }
cout<<ans<<endl;
}

最新文章

  1. SAP CRM 客户控制器与数据绑定
  2. 基于Quick-cocos2d-x的资源更新方案 一
  3. PHP获取一年有几周以及每周开始日期和结束日期
  4. DotNetOpenAuth使用笔记
  5. ORACLE 12C PDB 维护基础介绍
  6. DEF2015丨腾讯优测携专业云测试服务,亮相中国(成都)数字娱乐节
  7. robots.txt用法
  8. linux入门教程(五) Linux系统的远程登录
  9. C语言内存调试技巧—C语言最大难点揭秘
  10. 最短路径:Dijkstra,Bellman,SPFA,Floyd该算法的实施
  11. Mac下将ISO写入U盘镜像
  12. Android 安全加密
  13. 【转】WPF 从FlowDocument中找到Hyperlink
  14. java虚拟机内存区域
  15. SSM框架中写sql在dao文件中以注解的方式
  16. Python开发【内置模块篇】
  17. Google瓦片地图URL
  18. LOJ #6432. 「PKUSC2018」真实排名(组合数)
  19. ORACLE中Drop table cascade constraints之后果.
  20. Application.DoEvents()和多线程

热门文章

  1. CSV解析
  2. MFC技术积累——基于MFC对话框类的那些事儿4
  3. hdu6290 奢侈的旅行
  4. 查看本机的ip地址
  5. reciting
  6. python关于入参中,传入的是指针还是引用
  7. 如何在windows 2008 IIS7 上实现AD域的访问控制
  8. django authentication
  9. P2756 网络流解决二分图最大匹配
  10. python 05 关于对python中引用的理解