zoukankan      html  css  js  c++  java
  • MapGuessing TopCoder

    MapGuessing TopCoder - 12152

    做得我很迷

    首先是可以把问题转化为,每次操作之后会让原序列的限制条件变为:不考虑某一些位置时合法

    枚举每个开始位置,依次考虑每一个操作,如果有一个位置被改为不同,就是不合法的

    对于每一个开始位置,能得到的的最优限制条件都是唯一的,因为只要是合法的,一定取最后一个合法的位置,才能尽可能多地覆盖一些位置

    那么我们得到了(|goal|)个这样的限制条件(S_i),设(n=|goal|)

    直接计算肯定会算重,考虑一个简单的容斥

    (egin{aligned}Answer=sum_{T e empty}(-1)^{|T|+1}2^{|S_{T_1}cap cdots cap S_{T_{|T|}}|}end{aligned})

    就是枚举选择一个限制的集合,求出他们的并集

    直接枚举复杂度当然是(O(2^{|n|})),如果( ext{dfs})枚举,当前状态为(0)时,可以直接返回答案

    估计一下这个( ext{dfs})的复杂度

    设操作过程中指针左右移动的距离是(L),那么最多存在(n-L)个合法的开始位置,每个状态最多包含(L)(1)

    很显然枚举的上限是(min{2^{n-L},2^{L}}),即受到开始位置的个数可能出现的1个数的限制

    (n-L=L)时,复杂度达到上限是(O(2^{frac{n}{2}}))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
    
    set <ll> st;
    ll S[40];
    int now[40],cnt;
    ll dfs(int p,ll State){
    	if(p==cnt+1) return (1ll<<__builtin_popcountll(State)); // 枚举完毕
    	if(State==0) return 0; // 剪枝,注意因为是后面的所有1,-1相加,所以是return 0而不是1
    	return dfs(p+1,State)-dfs(p+1,State&S[p]);  // 直接处理容斥系数
    }
    
    class MapGuessing {
    public:
    	long long countPatterns(string S, vector <string> code) {
    		string C="";
    		for(string t:code) C+=t;
    		int n=S.size();
    		st.clear();
    		rep(i,0,n-1) {
    			int p=i,f=1;
    			ll lst=0; // 记录最后一个合法的即可
    			rep(i,0,n-1) now[i]=0;
    			for(char c:C) {
    				if(c=='<') p--;
    				if(c=='>') p++;
    				if(c=='0') now[p]=1;
    				if(c=='1') now[p]=2;
    				if(p<0 || p>=n){ f=0; break; }
    				int fl=1;
    				ll T=0;
    				rep(i,0,n-1) {
    					if(!now[i]) continue;
    					if(now[i]-1!=S[i]-'0'){ fl=0; break; }
    					else T|=1ll<<i;
    				}
    				if(!fl) continue;
    				lst=T;
    			}
    			if(!f) continue;
    			st.insert(-lst);
    		}
    		cnt=0;
    		for(ll x:st) {
    			ll y=-x;
    			int f=1;
    			rep(i,1,cnt) if((::S[i]&y)==y){ f=0; break; }
    			if(f) ::S[++cnt]=y;
    		}
            //初始系数是-1
    		ll ans=(1ll<<n)-dfs(1,(1ll<<n)-1); // 注意枚举出来会把T=emptyset的情况算进去,要去掉
    		return ans;
    	}
    };
    
    
  • 相关阅读:
    携程 去呼呼 Odoo SSO 单点登录
    Spring Boot 2.2 正式发布,大幅性能提升 + Java 13 支持 & Spring Data Moore M2
    全球顶尖AI技术 微软CRM X 销售易CRM Gartner魔力象限
    职场的真相——七句话
    东软 UniEAP SaCa DataViz & Report
    UML建模——活动图(Activity Diagram)
    领域驱动设计(DDD)部分核心概念
    阿里云RPA4.0背后的黑科技
    Open Source In-Memory Computing Platform
    Mac OS X ifconfig命令解释
  • 原文地址:https://www.cnblogs.com/chasedeath/p/13111698.html
Copyright © 2011-2022 走看看