0
点赞
收藏
分享

微信扫一扫

信息学奥赛一本通 1225:金银岛 | OpenJudge NOI 4.6 1797:金银岛

猎书客er 2022-03-27 阅读 7
c++贪心

【题目链接】

ybt 1225:金银岛
OpenJudge NOI 4.6 1797:金银岛

【题目考点】

1. 贪心

2. 部分背包问题

【解题思路】

该题为部分背包问题

1. 贪心选择性质的证明:

贪心选择:每次尽量多地选择单位价值最高的金属
单位价值:金属的价值除以重量,即 v i / n i v_i/n_i vi/ni

  1. 证明:存在最优解包含第一次贪心选择
  1. 证明:前k次都进行贪心选择,最优解包含第k+1次贪心选择

2. 具体做法

将所有金属按单位价值 v i / n i v_i/n_i vi/ni降序排序,顺序遍历

  • 如果该金属重量小于等于剩余可放重量,那么选择该金属的全部重量,统计其价值。
  • 如果该金属重量大于剩余可放重量,那么选择该金属的重量为:剩余可放重量,统计这部分金属的价值。

输出选择的金属的总价值。

【题解代码】

解法1:贪心

#include<bits/stdc++.h>
using namespace std;
#define N 105
struct Metal
{
    double n, v;
};
bool cmp(Metal a, Metal b)
{
    return a.v/a.n > b.v/b.n;
}
int main()
{
    int k, w, s;
    Metal m[N];
    cin >> k;
    while(k--)
    {
        double totVal = 0;
        cin >> w >> s;
        for(int i = 1; i <= s; ++i)
            cin >> m[i].n >> m[i].v;
        sort(m+1, m+1+s, cmp);
        for(int i = 1; i <= s; ++i)
        {
            if(w >= m[i].n)//w:剩余可放重量 
            {
                totVal += m[i].v;
                w -= m[i].n;
            }
            else
            {
                totVal += m[i].v/m[i].n*w;
                break;
            }
        }
        cout << fixed << setprecision(2) << totVal << endl;
    }
    return 0;
}
举报

相关推荐

0 条评论