zoukankan      html  css  js  c++  java
  • b_pat_找更多硬币(求字典序最小的具体方案)

    find more coin

    有一天,她去了一家宇宙购物中心购物,结账时可以使用各种硬币付款。
    但是,有一个特殊的付款要求:每张帐单,她都必须准确的支付所消费金额。

    输入格式
    第一行包含两个整数 N 和 M,分别表示硬币数量以及需要支付的金额。
    第二行包含 N 个整数,表示每个硬币的面额。
    输出格式
    共一行,按照面额升序的顺序,输出用来支付的所有硬币的面额。
    如果支付方式不唯一,则输出最小的支付面额序列。
    如果无解,则输出 No Solution。
    对于两个序列 {A[1], A[2], ...} 和 {B[1], B[2], ...},如果存在 k≥1 使得所有 i<k,满足 A[i]=B[i] 成立,并且 A[k]<B[k],则我们称序列 A 小于序列 B。
    数据范围
    1≤N≤10^4,
    1≤M≤100,
    硬币面值不超过 100

    输入样例1:
    8 9
    5 9 8 7 2 3 4 1
    输出样例1:
    1 3 5
    

    方法一:dp

    题目描述的不是特别的准确,也没说硬币只能用一次还是无限使用。但有两点很明确:

    • 支付方式可能不唯一
    • 输出最小的支付面额序列(下面会讲到)

    • 定义状态
      • f[i] ...
      • g[i][j] 表示对于第 i 个硬币在背包容量为 j 时的选择状态(g 即下文的 chose 数组)
    • 思考初始化:
      • f[...]=0,g[..][...]=0;
    • 思考状态转移方程
      • f[j]=f[j-A[i]]+A[i],g[i][j]=1;if (f[j]<=f[j-A[i]+A[i])(因为要字典序最小,当逆序排列后,如果每次有合法的状态都取更新 chose 数组,这样就一定可以取到字典序最小的方案)
    • 思考输出 ...

    为什么按升序排列取第一种方案不行呢?

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e4+5, M=105;
    int f[M], w[N], chose[N][M];
    bool cmp(int a, int b) {
        return a>b;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int n,m; cin>>n>>m;
        for (int i=0; i<n; i++) cin>>w[i];
        sort(w, w+n, cmp);
    
        for (int i=0; i<n; i++)
        for (int j=m; j>=w[i]; j--) if (f[j-w[i]]+w[i]>=f[j]) {
            f[j]=f[j-w[i]]+w[i];
            chose[i][j]=1;
        }
    
        if (f[m]==m) {
            int j=m;
            vector<int> ans;
            for (int i=n-1; i>=0 && j; i--) if (chose[i][j]) {
                ans.push_back(w[i]);
                j-=w[i];
            }
            cout<<ans[0];
            for (int i=1; i<ans.size(); i++) {
                cout<<' '<<ans[i];
            }
        } else {
            cout<<"No Solution";
        }
        return 0;
    }
    

    复杂度分析

    • Time\(O(nm)\)
    • Space\(O(m)\)
  • 相关阅读:
    TCP 连接状态
    可视化垃圾回收算法
    flume-ng+Kafka+Storm+HDFS 实时系统搭建
    WeX5 IDE 手机移动开发+JAVA +大数据
    云计算高级运维工程师
    CentOS 5.8 上安装 systemtap-2.6
    SYSTEMTAP -ORACLE
    Apple激活日期查询
    Div 浮动到另一个div之上
    Python模块常用的几种安装方式
  • 原文地址:https://www.cnblogs.com/wdt1/p/13605840.html
Copyright © 2011-2022 走看看