DAG动态规划-硬币问题

题目:有n种硬币,面值分别为V1,V2,...Vn,每种都有无限多。给定非负整数S,可以选用多少个硬币,使得面值之和恰好为S?输出硬币数目的最小值和最大值!

#include <bits/stdc++.h>

using namespace std;
int n, m, t;
const int INF = 0x3f3f3f3f;
int a[1005],Max[1005],Min[1005];
void dfs(int *d, int s)
{
    for(int i=1; i<=n; i++)
    if(s>=a[i] && d[s] == d[s-a[i]]+1){
        printf("%d ",i);
        dfs(d,s-a[i]);
        break;
    }
}

int main()
{
    cin >> n >> m;
    for(int i=1;i<=n; i++) cin>>a[i];
    for(int i=1;i<=m;i++){
        Min[i]=INF;
        Max[i]=-INF;
    }
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            if(i >= a[j]){
                Max[i] = max(Max[i-a[j]]+1,Max[i]);
                Min[i] = min(Min[i-a[j]]+1,Min[i]);
            }
        }
    }
    cout << Max[m] <<' '<< Min[m] << endl;
    dfs(Max,m);
    cout<<endl;
    dfs(Min,m);
}
/*
3 8
1 2 4
*/

#include <bits/stdc++.h>

using namespace std;
int n, m, t;
const int INF = 0x3f3f3f3f;
int a[1005],Max[1005],Min[1005],Max_[1005],Min_[1005];
void dfs(int *d, int s)
{
    for(int i=1; i<=n; i++)
    if(s>=a[i] && d[s] == d[s-a[i]]+1){
        printf("%d ",i);
        dfs(d,s-a[i]);
        break;
    }
}
void print(int *d, int s)
{
    while(s){
        printf("%d ",d[s]);
        s -= a[d[s]];
    }
}
int main()
{
    cin >> n >> m;
    for(int i=1;i<=n; i++) cin>>a[i];
    for(int i=1;i<=m;i++){
        Min[i]=INF;
        Max[i]=-INF;
    }
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            if(i >= a[j]){
                if(Min[i] > Min[i-a[j]]+1){
                    Min[i] = Min[i-a[j]]+1;
                    Min_[i] = j;
                }
                if(Max[i] < Max[i-a[j]]+1){
                    Max[i] = Max[i-a[j]]+1;
                    Max_[i] = j;
                }
            }
        }
    }
    cout << Max[m] <<' '<< Min[m] << endl;
    //dfs(Max,m);
    print(Max_,m);
    cout<<endl;
    //dfs(Min,m);
    print(Min_,m);
}
/*
3 8
1 2 4
*/

posted @ 2018-05-08 21:11  Roni_i  阅读(295)  评论(0编辑  收藏  举报