http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1268&judgeId=193772
给出n = 20个数,问其是否有和为k的情况
分两段,用O(2^(n / 2))复杂度维护出每一段的所有情况。
然后枚举第一段,二分判断第二段是否也有k - first
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> map<int, bool>dp1; set<int>dp2; void work() { int n, k; scanf("%d%d", &n, &k); dp1[0] = true; dp2.insert(0); for (int i = 1; i <= n / 2; ++i) { int x; scanf("%d", &x); map<int, bool> :: iterator it = dp1.end(); it--; while (true) { dp1[it->first + x] = true; if (it == dp1.begin()) break; it--; } } for (int i = n / 2 + 1; i <= n; ++i) { int x; scanf("%d", &x); set<int> :: iterator it = dp2.end(); it--; while (true) { dp2.insert(*it + x); if (it == dp2.begin()) break; it--; } } for (map<int, bool> :: iterator it = dp1.begin(); it != dp1.end(); ++it) { if (dp2.count(k - it->first)) { cout << "Yes" << endl; return; } } cout << "No" << endl; return; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }