DAG model-coin (dynamic programming, memory search)

DAG model-coins
There are n kinds of coins with denominations of V1, V2,..., Vn, and each has an infinite number. Given a non-negative integer S, how many coins can be used so that the sum of face value is exactly S? Output the minimum and maximum number of coins. 1<=n<=100,0<=S<=10000,1<=Vi<=S.

Idea:
The essence of this question is still the path problem of DAG. Each face value is regarded as a point, and the states maxv(x) and minv(x) are set to represent the longest and shortest paths from the current node to the 0 node, respectively. Find the state transition equation, the initial state is S, and select the optimal solution.
It should be noted that memorized search can reduce a lot of time, but the path in the result of this question can be 0, so all are marked with -1 to distinguish, if it is greater than or equal to 0, it means that the calculation has been performed, and the value is directly returned, otherwise it is marked as 0 , And then perform search calculations.
But this will cause errors. There may be no solution to this question, that is, the point cannot be found at the end, and S is not collected, then it will mistakenly think that it was found. Therefore, the calculated values ​​should be distinguished by other special values, that is, the minimum value and the maximum value. The initial state is all marked with -1, and only the end point is marked with 0.

code show as below:

#include <iostream>
#include <algorithm>
#include <string.h>
#define maxn 105
#define maxvn 10005
using namespace std;
int n,s;
int v[maxn],maxv[maxvn],minv[maxvn];
int dpmax(int s)
{
    
    
 int i;
 int& ans=maxv[s];
 if(ans!=-1)
 return ans;
 ans=-(1<<30);
 for(i=1;i<=n;i++)
 {
    
    
  if(s>=v[i])
  {
    
    
   ans=max(ans,dpmax(s-v[i])+1);
  }
 }
 return ans;
}
int dpmin(int s)
{
    
    
 int i;
 int& ans=minv[s];
 if(ans!=-1)
 return ans;
 ans=(1<<30);
 for(i=1;i<=n;i++)
 {
    
    
  if(s>=v[i])
  {
    
    
   ans=min(ans,dpmin(s-v[i])+1);
  }
 }
 return ans;
}
int print_max(int s)
{
    
    
 int i;
 for(i=1;i<=n;i++)
 {
    
    
  if(s>=v[i]&&maxv[s]==maxv[s-v[i]]+1)
  {
    
    
   cout<<v[i]<<" ";
   print_max(s-v[i]);
   break;
  }
 }
}
int print_min(int s)
{
    
    
 int i;
 for(i=1;i<=n;i++)
 {
    
    
  if(s>=v[i]&&minv[s]==minv[s-v[i]]+1)
  {
    
    
   cout<<v[i]<<" ";
   print_min(s-v[i]);
   break;
  }
 }
}
int main()
{
    
    
 int i;
 cin>>n>>s;
 for(i=1;i<=n;i++)
 {
    
    
  cin>>v[i];
 }
 memset(maxv,-1,sizeof(maxv));
 maxv[0]=0;
 memset(minv,-1,sizeof(minv));
 minv[0]=0;
 cout<<"min="<<dpmin(s)<<endl;
 cout<<"The Path Of Min:"<<endl;
 print_min(s);
 cout<<endl;
 cout<<"max="<<dpmax(s)<<endl;
 cout<<"The Path Of Max:"<<endl;
 print_max(s);
 cout<<endl;
 return 0;
} 

Guess you like

Origin blog.csdn.net/HT24k/article/details/106251537