zoukankan      html  css  js  c++  java
  • 【BZOJ4416】 [SHOI2013] 阶乘字符串(状压DP)

    点此看题面

    大致题意: 对于一个由前(n)个小写字母组成的字符串,若前(n)个小写字母的全排列都是该字符串的子序列,则称这个字符串为阶乘字符串。求验证给定字符串是不是阶乘字符串。

    前言

    (Jan 27th)刷题计划(2/6),算法标签:DP。

    这道题的状压(DP)好像是挺简单的,但(n>21)无解这个结论没想到,看了题解也不会证,只好昧着良心过了这道题。

    一个不会证的结论

    首先,先扔出一个结论:(n>21)时答案必然为(NO)

    证明?一脸懵逼,完全不会。

    只想吐槽题解里很多人说是因为(C_{450}^{21}<21!),这就更让我懵逼了,明明(C_{450}^{21})(26!)还要大,怎么就小于(21!)了......

    所以,这个证明就坑在这里了吧。

    状压(DP)

    这道题的状压(DP)还是挺好推的。

    (f_i)(i)是前(n)个小写字母的一个子集)表示至少要到字符串第(f_i)位才能使这部分字符串中存在子集(i)中所有小写字母的全排列。

    考虑如何转移,可以想到,如果我们删去集合中一个元素(j)(设删去该元素后的集合为(i-j)),那么就要满足对于任意(j),使得在(i-j)这个集合中所有小写字母全排列存在之后,还有元素(j)

    如果我们设(g_{i,j})表示字符串中第(i)位后第一个字符(j)所在的位置(如果第(i)位之后无(j),则(g_{i,j}=strlen+1)),那么就可以得到转移方程式:

    [f_i=max{g_{f_{i-j},j}|j∈i} ]

    其中之所以是(max),是因为要对于任意(j)都满足。

    (g)的预处理应该是比较简单的,可以直接见代码。

    最后如果(n=strlen+1),说明是(No),否则是(Yes)

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 21
    #define SL 450
    #define Gmax(x,y) (x<(y)&&(x=(y)))
    using namespace std;
    int n,p,l,f[1<<N],g[SL+5][N+5];string s;
    int main()
    {
    	RI Tt,i,j;cin>>Tt;W(Tt--)
    	{
    		if(cin>>n>>s,l=s.length(),s="#"+s,n>21) {puts("NO");continue;}//n>21直接输出No
    		for(i=1;i<=n;++i) g[l][i]=g[l+1][i]=l+1;//初始化g的边界
    		for(i=l-1;~i;--i) {for(j=1;j<=n;++j) g[i][j]=g[i+1][j];g[i][s[i+1]&31]=i+1;}//初始化g
    		for(p=1<<n,i=0;i^p;++i) for(f[i]=0,j=1;j<=n;++j) i&(1<<j-1)&&Gmax(f[i],g[f[i^(1<<j-1)]][j]);//动态规划
    		puts(f[p-1]==l+1?"NO":"YES");//判断是否可行
    	}return 0;
    }
    
  • 相关阅读:
    转 Android的消息处理机制
    转 Android的消息处理机制(图+源码分析)——Looper,Handler,Message
    Android如何获取开机启动项列表
    在Android里完美实现基站和WIFI定位
    managedQuery和query的区别,
    Android WIFI 操作
    转:Android 获取Root权限
    CocoaPods: 制作cocoapods国内镜像
    CentosOS 7: 创建Nginx+Https网站
    Mac: 通过蓝牙用安卓手机向Mac发送文件
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ4416.html
Copyright © 2011-2022 走看看