zoukankan      html  css  js  c++  java
  • AT3963 [AGC024F] Simple Subsequence Problem 题解

    ATcoder
    Luogu

    Description.

    给定 \(m\) 个长度不超过 \(n(n\le 20)\)01 串。
    找到字典序最小的字符,使它是至少 \(K\) 个字符串的子序列。

    Solution.

    首先考虑一个暴力做法,\(dp_{S,T}\) 表示当前答案字符串是 \(T\),待匹配串是 \(S\) 的答案。
    每次转移是对 \(T\) 加字符,\(S\) 中找到第一个 \(T\) 插入的字符并把它前面的全都删掉。
    发现有个性质,就是 \(|S|+|T|\le n\),通过刚刚转移过程可以得知。
    然后空间复杂度就成为了 \(O(2^n\cdot n^2)\)
    \(n^2\) 是因为两个字符串长度都不知,需要两维维护。

    考虑怎么把 \(O(n^2)\rightarrow O(n)\)
    发现在开头插入一个 1,然后每次找到第一个 1 即可。

    Coding.

    点击查看代码
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}/*}}}*/
    int n,K,nx[1<<21][2],dp[1<<21][21],tn[1<<21];char ch[1<<21];
    inline void output(int x,int w) {for(int i=x-1;~i;i--) putchar(((w>>i)&1)^48);putchar('\n');}
    int main()
    {
    	read(n,K);for(int i=0;i<=n;i++)//dp[A][l] -> A=S|T,l 是 T 长度,T 是目标串
    		{scanf("%s",ch);for(int j=0;j<(1<<i);j++) dp[j|(1<<i)][i]=ch[j]^48;}
    	for(int i=n;~i;i--) for(int j=0;j<(1<<i);j++) for(int k=i;~k;k--) if(dp[(1<<i)|j][k])
    	{
    		int v=dp[(1<<i)|j][k],S=j>>k,T=j&((1<<k)-1);if(k) dp[(1<<(i-k))|S][0]+=v;
    		if(T)
    		{
    			int u=k-1;while(!((T>>u)&1)) u--;
    			dp[(1<<(i-k+u+1))|(S<<(u+1))|(1<<u)|(T&((1<<u)-1))][u]+=v;
    		}
    		if((~T)&((1<<k)-1))
    		{
    			int u=k-1;while((T>>u)&1) u--;
    			dp[(1<<(i-k+u+1))|(S<<(u+1))|(T&((1<<u)-1))][u]+=v;
    		}
    	}
    	for(int i=n;~i;i--) for(int j=0;j<(1<<i);j++) if(dp[(1<<i)|j][0]>=K) return output(i,j),0;
    }
    
  • 相关阅读:
    记一次centos7.2下用crontab执行定时任务的过程(初级)
    海外手机号码正则匹配
    装了wamp之后,80端口被占用解决办法
    newtonsoft动态修改JObject
    .net正则提取手机号码,并替换带有手机号码的a标签
    .vs目录有什么用?
    centos7安装nginx-1.13.6 新手入门,图文解析
    centos7安装kafka_2.11-1.0.0 新手入门
    centos7安装apache 新手入门 图文教程
    面向对象——案例练习(4)判断点是否在圆的内部
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15407091.html
Copyright © 2011-2022 走看看