in this problem : https://codeforces.me/gym/104493/problem/A i know it is very slow to solve it using recursion but i want to know the solution using recursion to understand dp solution well here is my code it is WA2 :
int n;
int a[N] ;
ll sum=0;
ll mx=0;
int fr[11] ;
bool ok(int r){
ll x = a[r] ;
while(x > 0){
fr[x%10]++;
x/=10;
}
for(int i=0;i<10;i++){
if(fr[i] > 2)return 0;
}
return 1;
}
void del(int r){
ll x = a[r] ;
while(x > 0){
fr[x%10]--;
x/=10;
}
}
bool vis[N] ;
void rec(int r){
if(r == n){
mx = max(mx , sum) ;
return ;
}
if(ok(r)){sum+=a[r];vis[r]=1;}
else (del(r));
rec(r + 1) ;
if(vis[r]){sum-=a[r] ; vis[r]=0;del(r);}
rec(r+1);
}
void solve(){
cin >> n;
for(int i=0;i<=n;i++)vis[i]=0;
sum = mx = 0 ;
for(int i=0;i<10;i++)fr[i]=0;
for(int i=0;i<n;i++)cin>>a[i];
rec(0);
cout<<mx<<"\n";
}








Seems ok, just use long long array to store
a.Also, I propose (to make the code structure better) to make changes to
sumandvisonly inside corresponding functions (okanddel). The function should perform a certain self-sufficient work, and in your case adding a weight to the set is done withif (ok) { sum += a[r], vis[r] = 1; } else del(r);. It is not an atom, the bigger code is, the easier is to have a mistake somewhere. For example, I consider the following structure much better.Do you have idea how to solve it using dp recursion
Your recursion is of kind
You can add memoization to avoid going into the same state more than one time, like in the following.
In your case, the variables that define current state are
r,fr,sum,vis. There are two much of them to remember them all, so we would do some clever things.visin fact is not needed, for fixedrwe ask onlyvis[r]. That's the key idea of dynamic programming -- forget the information from previous steps, that doesn't affect the answer in the future. Here,vis[i]fori <= rindicates, whetheri-th weight was taken, or not, and it doesn't affect our choice in the future.vis[i]fori > ris always false.I don't know, how to say it in general case, but here you don't need
sumtoo. It doesn't affect your choice (whether we can take a next weight or not). It affects the answer, but nevertheless, it just adds something to it.What I want to say is that you can write the function in a style that it doesn't know
sum, but returns the optimal answer to the suffixa[r+1..n]. Then ifsumis sum fora[1..r]andansis best choice fora[r+1..n], you can setmx = max(mx, sum + ans).With those two changes, you have a recursion with relatively few parameters, and you can remember answer for all of them:
To store the best ans for a current state you should use any data structure — multi-dimensional array or map. Map is easier (you can replace
frwithvector, than usemap<pair<int, vector<int>>, int> memolike thismemo[{r, fr}] = ans), but it adds extra log factor to the complexity, so the solution might be too slow.Note that the total number of states is not so big. For correct states
fr[d] = 0,1,2, therefore the total number of states is no more than $$$3^{10} \cdot n$$$. It should fit in the limits.i solved it using dp and here is my solution if you need any help with it ask me XD
here