zoukankan      html  css  js  c++  java
  • Codeforces Round #590 (Div. 3)补题


    要想上2000分,先刷几百道2000+的题再说 ———某神

    题目 E F
    赛时是否尝试 × ×
    tag math bitmask
    难度 2000 2400
    状态

    E

    待定


    F

    传送门
    第一次接触状态压缩dp的题。这道题转换问题的思路非常巧妙。
    原问题:
    已知: 一个字符串,可进行不超过一次操作
    操作限定: 选择某个子串,使其在原串中翻转
    目的:使原串的特征值最大
    串的特征值:串任意没有重复字符的子串,其包含字符的种类数

    问题的转换:
    首先选定一个子串a,之后再找到另一个子串b,使得a与b没有公共的字符,枚举a与b,就能求出最大的特征值(如果a与b相邻,则翻转b即可,反之,将a与b之间的区间与b连接在一起进行翻转,即可将b翻转到a的相邻位置)
    因为合法子串的长度不会超过20位(题目限定),所以每个合法子串我们都可以将其用一个二进制长度为20的整型表示
    与a 01互补的“串”不一定出现在原串中,所以对于每一个串,我们都要求出其最大的合法长度,以便我们最后计算答案

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i = (a);i>=(b);--i)
    #define fo(i,a,b) for(int i =(a);i<(b);++i)
    #define de(x) cout<<#x<<" = "<<x<<endl;
    #define endl '
    '
    #define mem(a,b) memset(a,b,sizeof(a));
    #define ls(p) ((p)<<1)
    #define rs(p) (((p)<<1)|1)
    using namespace std;
    typedef long long ll;
    const int mn = 105;
    
    int main(){
    	string s;
    	cin >> s;
    	
    	vector <int> dp(1<<20);
    	for(int i = 0; i < int(s.size()); ++i){//  start char of substring
    		vector<bool> used(20);
    		int mask = 0;
    		for(int j = 0; i + j < int(s.size()); ++j){
    			if(used[s[i + j]-'a']) break; // current char has appear in the substring
    			used[s[i+j]-'a'] = true;        // update mask
    			mask |= 1<<(s[i+j]-'a');        // update dp hashtable
    			dp[mask] = __builtin_popcount(mask);
    		}
    	}
    	for(int mask = 0;mask < (1<<20);++mask){
    		for (int pos = 0; pos < 20;++pos) {
    			if((mask >> pos) & 1) {  
    				dp[mask] = max(dp[mask],dp[mask ^ (1 << pos)]);
    				//because mask ^ (1<<pos) < mask, dp[mask ^ (1 << pos)] have been iterated
       			}
    		}
    	}
    	
    	int ans = 0;
    	for(int mask = 0;mask < (1<<20);++mask) {
    		if(dp[mask] == __builtin_popcount(mask)){
    			/*
    				one interger's mask is absolutely less than or equal to itself
    				if mask unequals to itself ,that mean this substring do not appear
    				but it can show the complement string's max number
    			*/
    			int comp = ~mask & ((1 << 20)-1);
    			// get complement string's max number
    			ans = max(ans,dp[mask] + dp[comp]);
    		}
    	}
    	cout<<ans<<endl;
    }
    
    
  • 相关阅读:
    Camera
    iOS实现截屏 并合适保存
    将UIView转成UIImage,将UIImage转成PNG/JPG
    iOS7Status bar适配
    @synthesize obj=_obj的意义详解 @property和@synthesize
    iOS各种问题处理
    Foundation框架中的NSNumber对象详解
    iOS 文件和数据管理 (可能会删除本地文件储存)
    当ABAP遇见普罗米修斯
    一个工作13年的SAP开发人员的回忆:电子科技大学2000级新生入学指南
  • 原文地址:https://www.cnblogs.com/tea-egg/p/11626074.html
Copyright © 2011-2022 走看看