P1441 砝码称重
中文题
想法:
首先第一个要解决的问题就是在 n 个砝码中取 m 个 (因为数据量不是很大,我们可以考虑直接暴力)
当已知 m 个砝码的时候,求有多少中搭配的方式 (这个可以采取dp的方式)
#pragma GCC optimize(3,"Ofast","inline")//O3优化 #pragma GCC optimize(2)//O2优化 #include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #include <cstring> #define LL long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) const double eps = 1e-10; const int maxn = 30 + 10; const LL mod = 998244353; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; int a[maxn]; int vis[maxn]; int cnt,sum,ans; int n,m; int vised[2010]; void dp() { memset(vised,0, sizeof(vised)); vised[0] = 1; cnt = 0; sum = 0; for (int i = 1;i <= n;i++) { if (vis[i]) continue; sum += a[i]; for (int j = sum;j >= a[i];j--) { if (vised[j-a[i]] && j >= a[i] && !vised[j]) { vised[j] = 1; cnt++; } } } //cout << cnt << endl; ans = max(ans,cnt); } void dfs(int cur,int now) { if (now > m+1) return ; if (cur == n+1) { if (now == m+1) { dp(); } return ; } vis[cur] = 1; dfs(cur+1,now+1); vis[cur] = 0; dfs(cur+1,now); } int main() { ios::sync_with_stdio(0); cin >> n >> m; ans = 0; for (int i = 1;i <= n;i++) { cin >> a[i]; //sum += a[i]; } dfs(1,1); cout << ans << endl; return 0; }