zoukankan      html  css  js  c++  java
  • 折半搜索

    折半爆搜

    千篇一律

    基本数据范围在 (n<=40) 然后要搜索所有集合状态,

    折半爆搜即搜前一半,再搜后一半(顺便统计答案)总复杂度由(O(2^{40}))降到 (O(2^{20}))

    Incredible Cows

    (n)数分成两堆,使得两堆和的差最小。

    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<cstring>
    #include<map>
    #include<algorithm>
    using namespace std;
    const int N = 200005;
    int T, n, a[2][N], m[2];
    int h[N], f2[N], t[2], ans;
    void dfs(int flag, int x, int y) {
    	if (x > m[flag]) {
    		if (flag) f2[t[flag]] = y; 
    		else h[t[flag]] = y;
    		t[flag]++;
    		return;
    	}
    	dfs(flag, x + 1, abs(y + a[flag][x]));
    	dfs(flag, x + 1, abs(y - a[flag][x]));
    }
    int main() {
    	scanf("%d", &T);
    	while (T--) {
    		scanf("%d", &n);
    		t[0] = t[1] = 0;
    		m[0] = (n + 1) / 2;
    		m[1] = n / 2;
    		for (int i = 1; i <= m[0]; i++) scanf("%d", &a[0][i]);
    		for (int i = 1; i <= m[1]; i++) scanf("%d", &a[1][i]);
    		dfs(0, 1, 0);
    		dfs(1, 1, 0);
    		sort(h, h + t[0]);
    		sort(f2, f2 + t[1]);
    		ans = 0x3f3f3f3f;
    		for (int i = 0; i < t[0]; i++) {
    			int k = lower_bound(f2, f2 + t[1], h[i]) - f2;
    			if (k < t[1]) ans = min(ans, f2[k] - h[i]);
    		}
    		for (int i = 0; i < t[1]; i++) {
    			int k = lower_bound(h, h + t[0], f2[i]) - h;
    			if (k < t[0]) ans = min(ans, h[k] - f2[i]);
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    

    世界冰球锦标赛

    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    typedef long long LL;
    const int N=(1<<21);
    inline LL read() {
    	LL x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    int n,mid;
    LL m,a[2][45],l[N],r[N],t[2],ans;
    void dfs(int f,int x,LL sum) {
    	if(f&&x>n-mid) {
    		r[++t[1]]=sum;
    		return;
    	}
    	if(f==0&&x>mid) {
    		l[++t[0]]=sum;
    		return;
    	}
    	dfs(f,x+1,sum);
    	dfs(f,x+1,sum+a[f][x]);
    }
    int main() {
    	n=read();m=read();
    	mid=(n+1)/2;
    	for(int i=1;i<=mid;i++) a[0][i]=read();
    	for(int i=1;i<=n-mid;i++) a[1][i]=read();
    	dfs(0,1,0);
    	dfs(1,1,0);
    	sort(l+1,l+1+t[0]);
    	sort(r+1,r+1+t[1]);
    	for(int i=1;i<=t[0];i++) {
    		int k=upper_bound(r+1,r+1+t[1],m-l[i])-r-1;
    		ans+=k;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
    

    9.7模拟赛T2

    ([1,n])正着搜出来串存在(Map)里,然后([n+1,2n])搜出来串反着连接从(Map)里找相同的贡献答案

    #include <unordered_map>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    typedef long long LL;
    int n;
    char s[40];
    LL ans;
    unordered_map<string,int>mp;
    bool vis[40];
    void dfs1(int x) {
    	if(x==n+1) {
    		string s1,s2;
    		for(int i=1;i<=n;i++) 
    			if(vis[i]) s1+=s[i];
    		for(int i=n;i>=1;i--) 
    			if(!vis[i]) s2+=s[i];	
    		mp[s1+'#'+s2]++;
    		return;	
    	}
    	vis[x]=0;dfs1(x+1);
    	vis[x]=1;dfs1(x+1);
    }
    void dfs2(int x) {
    	if(x==2*n+1) {
    		string s1,s2;
    		for(int i=n+1;i<=2*n;i++) 
    			if(vis[i]) s1+=s[i];
    		for(int i=2*n;i>=n+1;i--) 
    			if(!vis[i]) s2+=s[i];	
    		ans+=mp[s2+'#'+s1]; 
    		return;	
    	}
    	vis[x]=0;dfs2(x+1);
    	vis[x]=1;dfs2(x+1);	
    }
    int main() {
    	scanf("%d%s",&n,s+1);
    	dfs1(1);
    	dfs2(n+1);
    	printf("%lld
    ",ans/2);
    	return 0;
    }
    
    
    

    11.9 模拟赛 hash_table

    很类似上面

    正着搜出来前一半串存在哈希表里,然后搜出来后一半从哈希表里找相反数贡献答案

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    const int N=7;
    const int inf=2147483647;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    void write(int x) {
    	static short st[33];short tp=0;
    	do st[++tp]=x%10,x/=10;while(x);
    	while(tp) putchar('0'|st[tp--]);
    	putchar('
    ');
    } 
    int n,m;
    int k[N],p[N],ans;
    int Pow[155][7];
    const int P=6974895;
    struct Hash_Tale {
    	int hd[P+5],to[P+5],nxt[P+5],tot,val[P+5];
    	inline void ins(int x) {
    		int v=(x%P+P)%P;
    		for(int i=hd[v];i;i=nxt[i]) {
    			if(to[i]==x) {
    				++val[i];return;
    			} 
    		}
    		to[++tot]=x;val[tot]=1;nxt[tot]=hd[v];hd[v]=tot;
    	}
    	inline int query(int x) {
    		int v=(x%P+P)%P;
    		for(int i=hd[v];i;i=nxt[i]) 
    			if(to[i]==x) 	
    				return val[i];
    		return 0;
    	}
    }Hash;
    void dfs1(int x,int sum) {
    	if(x==(n/2)+1) {
    		Hash.ins(sum);
    		return;
    	}
    	for(int i=1;i<=m;i++)
    		dfs1(x+1,sum+k[x]*Pow[i][p[x]]);
    }
    void dfs2(int x,int sum) {
    	if(x==n+1) {
    		ans+=Hash.query(sum);
    		return;
    	}
    	for(int i=1;i<=m;i++)
    		dfs2(x+1,sum-k[x]*Pow[i][p[x]]);
    }
    int main() {
    	n=read();m=read(); 
    	for(int i=1;i<=n;i++) {
    		k[i]=read();p[i]=read();
    	}
    	for(int i=1;i<=m;i++)
    		for(int j=0;j<=4;j++)
    			Pow[i][j]=j?Pow[i][j-1]*i:1;
    	dfs1(1,0);
    	dfs2(n/2+1,0);
    	write(ans);
    	return 0;
    }
    

    CF888E Maximum Subsequence

    给一个数列和(m),在数列任选若干个数,使得他们的和对(m)取模后最大(1<=n<=35)

    #include <set>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N=40;
    inline int read() {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return f*x;
    }
    int n,m,a[N],mid;
    set<int>st;
    void dfs1(int x,int sum) {
    	if(x==mid+1) {
    		st.insert(sum);
    		return;
    	}
    	dfs1(x+1,sum);
    	dfs1(x+1,(sum+a[x])%m);
    }
    
    int ans;
    void dfs2(int x,int sum) {
    	if(x==n+1) {
    		set<int>::iterator it=st.upper_bound(m-1-sum);
    		it--; 
    		ans=max(ans,sum+*it);
    		return;
    	}
    	dfs2(x+1,sum);
    	dfs2(x+1,(sum+a[x])%m);
    }
    int main() {
    	n=read();m=read();
    	mid=n/2;
    	for(int i=1;i<=n;i++) a[i]=read();
    	dfs1(1,0);
    	dfs2(mid+1,0);
    	printf("%d
    ",ans);
    	return 0;
    }
    

    wait

  • 相关阅读:
    How to Create a site at the specified URL and new database (CommandLine Operation)
    Using Wppackager to Package and Deploy Web Parts for Microsoft SharePoint Products and Technologies
    SQL Server Monitor v0.5 [Free tool]
    How to build Web Part
    Deploy web part in a virtual server by developing a Web Part Package file(.cab)
    How to recreate "sites" link if you delete it accidentally
    SharePoint Portal Server管理匿名访问设置
    Monitor sql connection from .Net SqlClient Data Provider
    Brief installation instruction of Sharepoint Portal Server
    How to Use SharePoint Alternate URL Access
  • 原文地址:https://www.cnblogs.com/ke-xin/p/13641103.html
Copyright © 2011-2022 走看看