[伯俊]1208部分数列の和2


燒伯準1208部分数列の和2

  • https://www.acmicpc.net/problem/745

  • 配列全体のサブセットの和=配列を2つの部分に分け,各部分の集合の和を加算して求める.
  • map容器使用説明
  • map mp
    ->mp[sum]:整数の和を格納するサブセットの個数
  • #include <iostream>
    #include <map>
    using namespace std;
    
    const int MAXN = 40;
    
    int n, s;
    long long cnt = 0;
    int num[MAXN + 1]; 
    map<int, int> mp;
    
    void dfsLeft(int index, int sum) {
    	if (index == n/2) {
    		++mp[sum];
    		return;
    	}
    	dfsLeft(index + 1, sum);
    	dfsLeft(index + 1, sum + num[index]);
    	return;
    }
    
    void dfsRight(int index, int sum) {
    	if (index >= n) {
    		cnt += mp[s-sum];
    		return;
    	}
    	dfsRight(index + 1, sum);
    	dfsRight(index + 1, sum + num[index]);
    	return;
    }
    
    int main() {
    	ios_base::sync_with_stdio(false);
    	cin.tie(NULL);
    	cout.tie(NULL);
    
    	cin >> n >> s;
    	for (int i = 0; i < n; ++i)
    		cin >> num[i];
    
    	dfsLeft(0, 0);
    	dfsRight(n/2, 0);
    
    	if (s == 0) cnt--;
    	cout << cnt;
    	return 0;
    }
  • の2つのアレイの部分集合は、それぞれ1つの共通集合を含む
    ->s=0の場合、答えはさらに大きくなります
    -> if (s == 0) cnt--;
  • ダブルポインタアルゴリズムを使用して解く
  • 計画学習
  • 📌参考資料

  • 白駿1208部分数列の和2解答(meeting in the medial)
    https://justicehui.github.io/ps/2019/03/24/BOJ1208/

  • 白準1208部分数列の和2(ダブルポインタ)を解く
    https://jaimemin.tistory.com/1107