最小邮票数

最小邮票数

http://www.nowcoder.com/questionTerminal/83800ae3292b4256b7349ded5f178dd1

思路

最简单的方法就是深搜了,就是逆序选择每一次可能选择的邮票。

#include<iostream>
#include<vector>

using namespace std;

int getCnt(int m, vector<int>& stamps, int index, int cnt){
    if(m == 0) return cnt;
    int ans = 20;
    //下一张邮票可能取 index ~ 0 中的某一张
    for(int i = index; i >= 0; i --){
        if(m == stamps[i]) ans = min(ans, cnt + 1);
        //如果邮票面额大于要凑齐的总值,自然不需要去选
        if(m > stamps[i]){
            int newCnt = getCnt(m - stamps[i], stamps, i - 1, cnt + 1);
            if(newCnt != 0){
                ans = min(ans, newCnt);
            }
        }
    }
    return ans == 20 ? 0 : ans;
}

int main(){
    int m, n;
    while(cin >> m >> n){
        vector<int> stamps(n);
        for(int i = 0; i < n; i ++)
            cin >> stamps[i];
        cout << getCnt(m, stamps, n - 1, 0) << endl;
    }
}

当然,更好的方法应该是动态规划,这其实是一个背包问题,背包容量为 m,放邮票使得邮票数最少。定义一个二维数组dpdp[i][j]表示用前i张邮票组成总值为j所需的最小邮票数。对于第i张邮票,其实我们只有两种选择啦,选或者是不选。那么选或者不选如何决定呢,这就要取决于怎样才能使得dp[i][j]的值最小啦。所以状态转移方程就是dp[i][j]=min(dp[i-1][j],dp[i-1][j-stamps[i]]+1)

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

const int MAX = 100000;

int main() {
    int m, n;
    while (cin >> m >> n) {
        vector<int> stamps(n + 1, 0);
        vector<vector<int>> dp(n + 1, vector<int>(m + 1, MAX));
        for(int i = 1; i <= n; i ++)
            cin >> stamps[i];
        dp[0][0] = 0;
        for (int i = 1; i <= n; i ++) {
            for (int j = 0; j <= m; j ++) {
                if (j < stamps[i]) {
                    dp[i][j] = dp[i - 1][j];
                    continue;
                }
                else {
                    dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - stamps[i]] + 1);
                }
            }
        }

        if (dp[n][m] == MAX)
            cout << 0 << endl;
        else
            cout << dp[n][m] << endl;
    }
    return 0;
}
算法题解 文章被收录于专栏

不定期更新一些算法题解,有什么问题可以随时留言~

全部评论
666
点赞 回复 分享
发布于 2024-03-05 10:59 安徽

相关推荐

12-19 22:04
武汉大学 Java
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-21 11:29
已编辑
斯卡蒂味的鱼汤:知道你不会来数马,就不捞你😂最近数马疯狂扩招,招聘要求挺低的,你能力肯定够,应该就是因为太强了,知道你不会来才不捞你
投递腾讯云智研发等公司10个岗位
点赞 评论 收藏
分享
评论
28
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务