C++做也不会,求大佬帮助谢谢

二:程序编写题

题目名称:小田的活动安排
题目描述:小田同学考试考了第一,妈妈奖励他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用1-5表示,第5等最重要。他从网上查到每件物品的价格(都是整数元)。他希望在不超N元的前提下,使得每件物品的价格与重要度的乘积总和最大。设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为j1,j2,...,jk,则所求的总和为:v[j1]*w[j1]+v[j2]*w[j2]+...+v[jk]*w[jk].请你帮小田设计一个满足要求的购物单。
输入描述:第一行,为2个整数n和m,用空格隔开,n为总钱数,m为希望购买物品的个数。接下来M行,给出相对应的物品数据,每行有两个非负整数v和p,v是价格,p是重要度(1-5).
输出描述:1个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值。
样例输入:
1000 5
800 2
400 5
300 5
400 3
200 2

经典的01背包问题,使用动态规划求解,C++代码如下:

#include <bits/stdc++.h> // C++万能头文件

using namespace std;

using pii = pair<int, int>; // 每个物品的价格和重要度

int main() {

    int n, m; // 商品总钱数和个数

    cin >> n >> m;    

    vector<pii> items; // 记录m件商品

    for (int i = 0; i < m; ++i) {

        int v, p; // 价格和重要度

        cin >> v >> p;

        items.emplace_back(v, p);

    }

    // dp[i][j]表示在前i件商品中选择,总价格不超过j的最大价格与重要度的乘积和

    vector<vector<int>> dp(m + 1, vector<int>(n + 1));

    for (int i = 1; i <= m; ++i) {

        auto [v, p] = items[i - 1]; // 当前商品的价格和重要度

        for (int j = 1; j <= n; ++j) {

            if (j < v) // 当前商品价格超过限制,不选

                dp[i][j] = dp[i - 1][j];

            else // 当前商品可选,取选或不选两者的较大值

                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v] + v * p);

        }  

    }

    int k = 0; // 统计所选商品的个数

    vector<bool> selected(m); // 标记选择哪些商品

    for (int i = m, j = n; i >= 1; --i) {

        if (dp[i][j] > dp[i - 1][j]) {

            selected[i - 1] = true; // 选择该商品

            ++k;

            j -= items[i - 1].first;

        }

    }

    cout << "共选了" << k << "件商品,最大价格与重要度的乘积和为" << dp[m][n] << "\n";

    cout << "所选商品的价格和重要度分别为:\n";

    for (int i = 0; i < m; ++i) {

        if (selected[i])

            cout << items[i].first << " " << items[i].second << "\n";

    }

    return 0;

}

实例输出结果为:

如果能帮到你,给个采纳哈~

温馨提示:答案为网友推荐,仅供参考
相似回答