P1441 砝码称重(状态压缩+bitset)
传送门
题目描述:
现有n个砝码,重量分别为 ai,在去掉 m 个砝码后,问最多能称量出多少不同的重量(不包括 0)。
请注意,砝码只能放在其中一边。
思路:dfs枚举出所有可能的选择方法,再在每种可能的方法中进行dp,
这道题由于是只有加法操作而且值比较小可以用bitset优化快速算出每个数的出现情况
#include<iostream> #include<string> #include<stack> #include<queue> #include<string.h> #include<map> #include<vector> #include<bitset> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; const int maxn = 21; #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r inline int read() { int f = 1, num = 0; char ch = getchar(); while (0 == isdigit(ch)) { if (ch == '-')f = -1; ch = getchar(); } while (0 != isdigit(ch)) num = (num << 1) + (num << 3) + ch - '0', ch = getchar(); return num * f; } int n, m,res; int w[maxn]; void dfs(int pos,int now, int num) { if (pos > n)return; if (num == n - m) { bitset<2010>S; S[0] = 1;//为0的可能 for (int i = 0; i < n; i++) { if (now & (1<<i)) { S |= S << w[i];//或就表示算上了之前的 } } if (res < S.count()) { res = S.count(); } return; } if(m+num>=pos+1)//剪枝 dfs(pos + 1, now, num); dfs(pos + 1, now + (1 << pos), num + 1); } int main() { //freopen("test.txt", "r", stdin); n = read(), m = read(); for (int i = 0; i < n; i++)w[i] = read(); dfs(0, 0, 0); cout << res-1 << endl;//要减去为0的可能 return 0; }

浙公网安备 33010602011771号