zoukankan      html  css  js  c++  java
  • 最少硬币问题


    动态规划的核心是状态和状态转移方程**

    • DAG上的动态规划一定要结合图来思考,要心中有图,或者在纸上画图,谨记!这样可以真正理解!求解状态转移方程的过程其实就是在填写一个表格!把表填好了,所有状态就填好了

    d(i)定义为以i开始到0结束的最长/短路


    /*

    最少硬币问题

    Sample Input#
    3
    23
    1 2 5

    Sample Output#
    6
    1 2 3 3 3 3
    */


    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    using namespace std;

    #define INF 1000000000

    const int maxn=105;
    int n;
    int S;
    int V[maxn];
    int d[maxn];


    void input()
    {
        cin>>n>>S;
        for(int i = 1; i <= n; i++) cin >> V[i];
    }

    //这里要注意表示dp的状态值: 因为最小值可能是0, 所以不能用0代表没算过,而是用-1代表没算过。INF代表不可达。
    int dp(int S)
    {
        int &ans=d[S];
        if(ans!=-1) return ans;

        ans=INF;//表示不可达
        for(int i=1;i<=n;i++)
            if(S>=V[i])
            {
                ans=min(dp(S-V[i])+1, ans);
            }
        return ans;
    }

    void print_ans(int* d, int S){
        for(int i=1;i<=n;i++)
            if(S>=V[i] && d[S-V[i]]+1==d[S])
            {
                cout<<i<< " ";
                print_ans(d, S-V[i]);
                break;
            }
    }

    int main()
    {
        input();
        memset(d, -1, sizeof(d));//-1代表没算过
        d[0]=0;//0的时候,不需要硬币

        int r = dp(S);
        if(r==INF) cout<< "no solution"<<endl;
        else
        {
            cout<< r <<endl;
            print_ans(d, S);
        }
    }


  • 相关阅读:
    代码规范
    svn的牛逼操作反向merge
    QT 半透明遮罩(弹窗)
    ACE库 ACE_Handle_Set类解析
    linux系统如何启用ftp服务
    vim color
    Linux动态库应用
    自建工程makefile文件
    Makefile工程文件
    linux杂记
  • 原文地址:https://www.cnblogs.com/cute/p/15068917.html
Copyright © 2011-2022 走看看