# Solution For Profitable Schemes

Problem statement:

Suppose you have n integers from 1 to n. We define a beautiful arrangement as an array that is constructed by these n numbers successfully if one of the following is true for the ith position (1 ≤ i ≤ n) in this array:

1. The number at the ith position is divisible by i.

2. i is divisible by the number at the ith position.

Given an integer n, return the number of the beautiful arrangements that you can construct.

Example 1:

Input: 2

Output: 2

Explanation:

The first beautiful arrangement is [1, 2]:

– Number at the 1st position (i=1) is 1, and 1 is divisible by i (i=1).

– Number at the 2nd position (i=2) is 2, and 2 is divisible by i (i=2).

The second beautiful arrangement is [2, 1]:

– Number at the 1st position (i=1) is 2, and 2 is divisible by i (i=1).

– Number at the 2nd position (i=2) is 1, and i (i=2) is divisible by 1.

Solution:

The problem involves finding all the beautiful arrangements, and the total count of such beautiful arrangements. The arrays should be constructed such that the two conditions mentioned in the problem statement hold. The brute force approach is to find all possible permutations of the given integers (1 to n), and then check if they satisfy the conditions mentioned in the problem statement.

This approach will not work for larger values of n, as the number of permutations increases exponentially. Thus, we need to come up with an algorithm to efficiently count the total number of beautiful arrangements.

Approach:

To count the total number of beautiful arrangements, we can use a recursive approach. The idea is to start with the first position of the array (i.e., index 1), and then find all the possible numbers that can be placed at this position. We can then recursively move to the next position (i.e., index 2), and again find all the possible numbers that can be placed at this position. We can repeat this process until we reach the end of the array.

To find the possible numbers that can be placed at a given position, we can use a bitmask approach. We can create a bitmask with n bits, where the ith bit is set to 1 if the number i has already been used in the array, and is 0 otherwise. We can then iterate over all the possible numbers that can be placed at the given position, and check if they satisfy the conditions mentioned in the problem statement.

If a number satisfies the conditions, we can mark it as used (set the corresponding bit in the bitmask to 1), and recursively move to the next position. We can then count the number of beautiful arrangements that can be constructed, using this approach.

Implementation:

We can start by defining a recursive function, which takes in the current position (i.e., index), a bitmask indicating which numbers have been used so far, and a count of the number of beautiful arrangements found so far.

“`

int countArrangements(int pos, int used, int count, int n) {

if (pos > n) {

count++;

return count;

}

```
for (int i = 1; i <= n; i++) {
if (!(used & (1 << i)) && (i % pos == 0 || pos % i == 0)) {
count = countArrangements(pos + 1, used | (1 << i), count, n);
}
}
return count;
```

}

“`

In this function, we first check if we have reached the end of the array (i.e., if the current position is greater than n). If we have, we increment the count of beautiful arrangements found and return it.

If we have not reached the end of the array, we iterate over all the possible numbers that can be placed at the current position. We check if the number has not been used before and if it satisfies the conditions mentioned in the problem statement. If it does, we mark it as used and recursively move to the next position.

We can then call this function with the initial parameters of pos = 1, used = 0, count = 0. This will give us the total count of beautiful arrangements that can be constructed.

`int countArrangement(int n) {`

return countArrangements(1, 0, 0, n);

}

This function simply calls the countArrangements function with the initial parameters, and returns the count of beautiful arrangements found.

Complexity analysis:

The time complexity of this approach is O(n * 2^n), where n is the number of integers from 1 to n. This is because we are iterating over all possible combinations of the numbers used in the array, and this can be represented as a bitmask of size n.

The space complexity of this approach is O(n), as we are using a bitmask to store which numbers have been used so far.

## Step by Step Implementation For Profitable Schemes

There are G people in a gang, and a list of various crimes they could commit. The i-th crime generates a profit[i] and requires group[i] gang members to participate. If a gang member participates in one crime, that member can't participate in another crime. Let's call a crime profitable if its profit is greater than or equal to P, and the gang doesn't need more than G members to participate in it. How many profitable schemes can the gang generate? class Solution { public int profitableSchemes(int G, int P, int[] group, int[] profit) { int[][] dp = new int[G + 1][P + 1]; dp[0][0] = 1; int res = 0, len = profit.length; for (int k = 0; k < len; k++) { int g = group[k], p = profit[k]; for (int i = G - g; i >= 0; i--) { for (int j = P - p; j >= 0; j--) { dp[i + g][j + p] += dp[i][j]; dp[i + g][j + p] %= 1000000007; } } } for (int[] row : dp) { for (int v : row) { res += v; res %= 1000000007; } } return res; } }

There are G people in a gang, and a list of various crimes they could commit. The i-th crime generates a profit[i] and requires group[i] gang members to participate. If a gang member participates in one crime, that member can't participate in another crime. Let's call a crime profitable if its profit is greater than or equal to P, and the gang doesn't need any more members to participate in it. How many profitable schemes can the gang generate? Note: 1 <= G <= 100 0 <= P <= 100 1 <= group[i] <= 100 0 <= profit[i] <= 100 1 <= sum(group) <= 100 class Solution: def profitableSchemes(self, G: int, P: int, group: List[int], profit: List[int]) -> int: dp = [[0] * (P + 1) for _ in range(G + 1)] dp[0][0] = 1 for i, (g, p) in enumerate(zip(group, profit)): for j in range(G - g, -1, -1): for k in range(P - p, -1, -1): dp[j + g][k + p] += dp[j][k] return sum(dp[-1])

var profitableSchemes = function(G, P, group, profit) { // G is the number of people in the group // P is the profit that you can make per person // group is an array of integers representing the people in each group // profit is an array of integers representing the profit you can make for each group // your code goes here };

There are G members in a secret gang, and a list of various crimes they could commit. The i-th crime generates a profit[i] and requires group[i] gang members to participate. If a gang member participates in one crime, that member can't participate in another crime. The total profit from a single crime requires that at least P members participate, and this is called a profitable scheme. Write a function that, given an integer G and a vector of integers profit and group, returns the number of profitable schemes. int profitableSchemes(int G, int P, vector& profit, vector & group) { int N = profit.size(); vector > dp(P + 1, vector (G + 1)); dp[0][0] = 1; for (int k = 1; k <= N; ++k) { int p = profit[k-1], g = group[k-1]; for (int i = P; i >= p; --i) { for (int j = G - g; j >= 0; --j) { dp[i][j+g] = (dp[i][j+g] + dp[i-p][j]) % 1000000007; } } } int res = 0; for (auto x: dp[P]) res = (res + x) % 1000000007; return res; }

using System; public class Solution { public int ProfitableSchemes(int G, int P, int[] group, int[] profit) { //G is the number of criminal groups //P is the minimum profit that the group must make //group is the number of criminals in each group //profit is the profit that the group will make int[,] dp = new int[G + 1, P + 1]; dp[0, 0] = 1; int mod = 1000000007; for (int i = 0; i < group.Length; i++) { for (int j = G - group[i]; j >= 0; j--) { for (int k = P - profit[i]; k >= 0; k--) { dp[j + group[i], k + profit[i]] += dp[j, k]; dp[j + group[i], k + profit[i]] %= mod; } } } int res = 0; for (int i = 0; i <= G; i++) { for (int j = 0; j <= P; j++) { res += dp[i, j]; res %= mod; } } return res; } }