Skip to content

Commit a0de84c

Browse files
authored
Merge pull request #5937 from Kiruthees/Cses2421
Added internal solution for Atcoder - Grouping
2 parents c3e4c25 + 37c5582 commit a0de84c

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

content/4_Gold/DP_Bitmasks.problems.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@
5252
"isStarred": false,
5353
"tags": ["Bitmasks", "DP"],
5454
"solutionMetadata": {
55-
"kind": "autogen-label-from-site",
56-
"site": "AC"
55+
"kind": "internal"
5756
}
5857
},
5958
{

solutions/gold/ac-grouping.mdx

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
id: ac-grouping
3+
source: AtCoder
4+
title: Grouping
5+
author: Kiruthees G
6+
---
7+
8+
[Unofficial Analysis (C++)](https://nwatx.me/post/atcoderdp)
9+
10+
## Explanation
11+
12+
We define $dp[i]$ as the maximum score possible for the subset of rabbits represented by mask $i$.
13+
14+
The transition involves two steps for each mask $i$:
15+
16+
1. **Base Score**: Initialize $dp[i]$ by calculating the sum of $a_{j,k}$ for all pairs $(j, k)$ within the mask. This assumes all rabbits in the mask form a single group.
17+
2. **Merging Subsets**: Improve $dp[i]$ by splitting the mask into two disjoint submasks $j$ and $i \oplus j$. The transition is:
18+
19+
$$
20+
dp[i] = \max_{j \subseteq i} \left(dp[i], dp[j] + dp[i \oplus j] \right)
21+
$$
22+
23+
24+
<Info>
25+
26+
Since $j$ is a subset of $i$, the XOR operation ($i \oplus j$) acts like set subtraction. It "toggles off" the bits that are present in $j$, leaving you with exactly the remaining bits of $i$. This guarantees that $j$ and $i \oplus j$ are disjoint parts that perfectly combine to form $i$.
27+
28+
For an efficient way to iterate over submasks $j$, we use the pattern `for (int j = i; j; j = (j - 1) & i)`. You can read more about this technique in the [Merging Subsets section](/gold/dp-bitmasks#merging-subsets) of the module.
29+
30+
</Info>
31+
32+
33+
## Implementation
34+
35+
**Time Complexity**: $\mathcal{O}(3^N + N^2 \cdot 2^N)$
36+
37+
<LanguageSection>
38+
<CPPSection>
39+
40+
```cpp
41+
#include <bits/stdc++.h>
42+
using namespace std;
43+
44+
using ll = long long;
45+
46+
int main() {
47+
ios_base::sync_with_stdio(false);
48+
cin.tie(nullptr);
49+
50+
int n;
51+
cin >> n;
52+
vector a(n, vector<int>(n));
53+
for (int i = 0; i < n; i++) {
54+
for (int j = 0; j < n; j++) { cin >> a[i][j]; }
55+
}
56+
57+
vector<ll> dp(1 << n);
58+
59+
// Iterate through every possible subset of rabbits
60+
for (int i = 1; i < (1 << n); i++) {
61+
// Calculate internal score if this subset forms ONE single group
62+
for (int j = 0; j < n; j++) {
63+
if (!(i >> j & 1)) continue;
64+
for (int k = j + 1; k < n; k++) {
65+
if (!(i >> k & 1)) continue;
66+
dp[i] += a[j][k];
67+
}
68+
}
69+
70+
// Iterate over all submasks j of the current mask i
71+
// Try splitting the mask into smaller groups to find a better score
72+
for (int j = (i - 1) & i; j > 0; j = (j - 1) & i) {
73+
dp[i] = max(dp[i], dp[j] + dp[i ^ j]);
74+
}
75+
}
76+
77+
cout << dp[(1 << n) - 1] << '\n';
78+
}
79+
```
80+
81+
</CPPSection>
82+
</LanguageSection>

0 commit comments

Comments
 (0)