zoukankan      html  css  js  c++  java
  • SP11469 SUBSET

    Description

    洛谷传送门

    Solution

    又是一道折半搜索题。

    我们还是枚举一半的数,记录每一种情况的和。

    然后爆搜另一半,当和为 (S) 时,判断前一半是否可以凑出 (S),如果可以,打个标记即可。

    两次凑出 (S) 时,可能会有重复选用的数组,但其实不用管。

    考虑到重复的话,两边同时删去同一个数也相等,但可能选用相同的数会多次出现,所以要打个标记。

    (dfs) 过程中,状压记录一下当前选用了哪些数,加和减状压相同的状态也可以,前面证明过重复的数没有影响了。

    这道题由于还需要找到和为 (S) 的状态有哪些,可以用一个 (vector) 存一下,但是和太大了。

    所以还要用一个 (map) 离散化一下,不是真正的离散化,因为不需要排序,只需要标记一下即可。

    代码还是比较容易理解的。

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <map>
    #include <vector>
    #define ri register int
    
    using namespace std;
    
    const int N = 30;
    const int S = (1 << 20) + 10;
    int n, mid, cnt;
    int a[N];
    map <int, int> mp;
    vector <int> g[S];
    bool vis[S];
    
    inline void dfs1(int x, int sum, int now){
    	// cout << "x  " << x << " " << now << endl;
    	if(x > mid){
    		if(!mp.count(sum)) mp[sum] = ++cnt;
    		g[mp[sum]].push_back(now);
    		return;
    	}
    	dfs1(x + 1, sum, now);
    	dfs1(x + 1, sum + a[x], now | (1 << (x - 1)));
    	dfs1(x + 1, sum - a[x], now | (1 << (x - 1)));
    }
    
    inline void dfs2(int x, int sum, int now){
    	if(x > n){
    		if(mp.count(sum)){
    			int t = mp[sum];
    			for(auto x : g[t])
    				vis[x | now] = 1;
    		}
    		return;
    	}
    	dfs2(x + 1, sum, now);
    	dfs2(x + 1, sum + a[x], now | (1 << (x - 1)));
    	dfs2(x + 1, sum - a[x], now | (1 << (x - 1)));
    }
    
    int main(){
    	scanf("%d", &n);
    	for(ri i = 1; i <= n; i++)
    		scanf("%d", &a[i]);
    	mid = n >> 1;
    	dfs1(1, 0, 0), dfs2(mid + 1, 0, 0);
    	ri ans = 0;
    	for(ri i = 1; i <= (1 << n); i++)
    		ans += vis[i];
    	printf("%d
    ", ans);
    	return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15379937.html

  • 相关阅读:
    [做题记录]数学#1
    [鸽鸽]
    有关VHDL中null, 在Verilog HDL 中的表示方法 YB
    有关Quartus如何自动生成 .pof 文件 YB
    javac、java命令如何编译运行目标类以及其类引入的外部jar包
    虚拟机装 CentOs 7 黑屏解决办法
    curl 访问https
    游戏命中判定:圆桌算法和程序实现
    Unity3d与dll文件
    C++异步网络库workflow及基于workflow实现的网络框架wfrest的安装使用心得
  • 原文地址:https://www.cnblogs.com/xixike/p/15379937.html
Copyright © 2011-2022 走看看