zoukankan      html  css  js  c++  java
  • [题解] [CF938F] Erasing Substrings

    题面

    题解

    发现这个操作的使用顺序是独立的
    所以后面的操作我们可以提前用, 前面的操作可以后面再去用
    考虑我们当前已经知道了最优解的前 (i) 项, 现在在求第 (i + 1)
    要达到最优解的方式当然有很多, 我们使用过的操作集合为 (s[])
    那么我们可以任选没有用过的操作, 设使用某些没有用过的操作之后, 集合变为了 (t[])
    由于我们知道我们在求第几项, 也可以根据 (t[]) 集合知道我们删掉了几个数
    所以我们可以推出使用集合为 (t[]) 时, 当前可以加入的字符是哪一个
    在所有这些可加入的字符中选取最优的
    那些达不到最优的使用集合 (t[]) 在更新 (i + 2) 的时候就不能作为 (i + 1)(s[])
    因为它代表的并不是最优的
    这样我们就可以从前 (i) 项的最优解推到第 (i + 1) 项了
    那么其实就是一个这样的思想
    每次从所有最优的情况把接下来合法的情况遍历一遍
    在这些合法的情况中选出最优的
    再把那些不是最优的合法情况置成不合法
    (f[i][s]) 为选取操作集合为 (s) 的时候, 最优解的第 (i) 项最优是多少
    转移就是普通的状压
    (i) 这一维可以滚掉
    具体实现可以看一下代码

    code

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    const int N = 5005; 
    using namespace std; 
    
    int n, f[N], k, sz, lst; 
    char s[N]; 
    
    template < typename T >
    inline T read()
    {
    	T x = 0, w = 1; char c = getchar();
    	while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return x * w; 
    }
    
    int main()
    {
    	scanf("%s", s + 1), n = strlen(s + 1);
    	for(int i = 0; i <= n; i++)
    		f[i] = 1;
    	k = log2(n), sz = 1 << k, lst = n - sz + 1;
    	for(int i = 1; i <= lst; i++)
    	{
    		char ch = 'z' + 1;
    		for(int j = 0; j < sz; j++)
    			if(f[j]) for(int l = 0; l < k; l++) f[j | (1 << l)] = 1;
    		for(int j = 0; j < sz; j++)
    			if(f[j]) ch = min(ch, s[i + j]); 
    		for(int j = 0; j < sz; j++) f[j] &= (s[j + i] == ch); 
    		putchar(ch); 
    	}
    	puts(""); 
    	return 0; 
    }
    
  • 相关阅读:
    mysql
    MySQL主从同步
    python与各数据库的交互
    snmptrap
    web场景的监控
    zabbix的历史数据存储到elasticsearch中
    使用PopupWindow的实现步骤
    使用PopupWindow的实现步骤
    ListView及其ArrayAdapter的应用
    ListView及其ArrayAdapter的应用
  • 原文地址:https://www.cnblogs.com/ztlztl/p/12792571.html
Copyright © 2011-2022 走看看