I was solving the Niceness of the Arrays problem (NICARRAY Problem - CodeChef) and I came up with the following backtracking solution which generates all the sets of integers for the missing values. Though the code gives the correct output but it is not efficient enough hence gives TLE in the second sub-task.
#include <bits/stdc++.h>
using namespace std;
void solve(int i, int n, int v, vector<int> solution, vector <vector<int>>& solutions, int prev)
{
if(i == n)
{
if(accumulate(solution.begin(), solution.end(), 0) == v)
{
solutions.push_back(solution);
return;
}
else
return;
}
else if(accumulate(solution.begin(), solution.end(), 0) > v)
{
return;
}
else
{
for(int j=1; j<=(v-n+1); j++)
{
if(j >= prev)
{
solution.push_back(j);
solve(i+1, n, v, solution, solutions, j);
solution.pop_back();
}
}
}
}
const long long MOD = 1e+9 + 7;
long long niceness(int a[], int len)
{
long long gcd_sum = 0;
for(int i=0; i<len-1; i++)
{
for(int j=i+1; j<len; j++)
{
gcd_sum += __gcd(a[i],a[j])%MOD;
}
}
return gcd_sum%MOD;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while(t--)
{
int N, S;
cin >> N >> S;
int sum = 0;
int A[N];
vector<int> missing;
for(int i=0; i<N; i++)
{
cin >> A[i];
if(A[i] > 0)
sum += A[i];
else
missing.push_back(i);
}
vector<int> sol;
vector <vector<int>> sols;
int target_val = S - sum;
int vars = missing.size();
solve(0, vars, target_val, sol, sols, 1);
int total_niceness = 0;
for(int i=0; i<sols.size(); i++)
{
do
{
for(int j=0; j<vars; j++)
A[missing[j]] = sols[i][j];
total_niceness += niceness(A, N)%MOD;
}while(next_permutation(sols[i].begin(), sols[i].end()));
}
cout << total_niceness%MOD << "\n";
}
return 0;
}
How can I improve this solution to get an AC? Please help.