圣遗物
分析:
发现除了第一个位置以外 每个位置都有两种选择
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
int n, fac = 1;
int Pow (int a, int k) {
int res = 1;
for (; k; a = 1ll * a * a % mod, k >>= 1)
if (k & 1) res = 1ll * res * a % mod;
return res;
}
int main () {
cin >> n;
for (int i = 1; i <= n; i++) fac = 1ll * fac * i % mod;
cout << 1ll * Pow(2, n - 1) * Pow(fac, mod - 2) % mod << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10, M = 13;
int n, k, m, f[N][M + 1][1 << M];
pair <int, int> a[N];
int main () {
scanf("%d%d%d", &n, &k, &m);
for (int num, idx, i = 1; i <= n; i++) {
scanf("%d%d", &a[i].first, &num);
while (num--) scanf("%d", &idx), a[i].second |= (1 << idx - 1);
}
sort(a + 1, a + n + 1);
int lim = (1 << m) - 1;
memset(f, 128, sizeof f), f[0][0][0] = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j <= m; j++)
for (int S = 0; S <= lim; S++) {
if (j < m) f[i + 1][j + 1][S | a[i + 1].second] = max(f[i + 1][j + 1][S | a[i + 1].second], f[i][j][S]);
if (n - i <= k - j) f[i + 1][j][S] = max(f[i + 1][j][S], f[i][j][S] + a[i + 1].first);
f[i + 1][j][S] = max(f[i + 1][j][S], f[i][j][S]);
}
long long ans = 0;
for (int j = 0; j <= m; j++)
for (int S = 0; S <= lim; S++)
ans = max(ans, 1ll * __builtin_popcount(S) * f[n][j][S]);
printf("%lld\n", ans);
return 0;
}
标签:int,res,d%,牛客,1ll,63,挑战赛,mod
From: https://www.cnblogs.com/wzxbeliever/p/16724985.html