【题解】小数背包问题

题目描述

        有一个背包,背包容量是M(0<M≤200),有N(1<N≤1000)个物品,物品可以分割成任意大小。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

 

输入格式

        第一行有两个数,M和N;

        第二行到第N+1行,第i行为第i-1个物品的价值和质量(均为小于100的正整数),中间用空格隔开。

 

输出格式

        只有一个数为最大总价值(保留一位小数)。

 

输入样例

150 7

10 35

40 30

30 60

50 50

35 40

40 10

30 25

输出样例

190.6

 

题解

        乍看之下是个dp背包问题,但是因为这里可以拆分成任意份,那么实际上只用按照单位性价比排序在取就好了。

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstdio>
#define MAXN 1001

using namespace std;

double m;
int n;
double ans;
struct node
{
    double vw;
    double val;
    double wei;
}a[MAXN];
bool cmp(node a, node b)
{
    if(a.vw != b.vw) return a.vw > b.vw;
    return a.wei < b.wei;
}

int main()
{
    cin >> m >> n;
    for(register int i = 1; i <= n; i++)
    {
        cin >> a[i].val >> a[i].wei;
        a[i].vw = a[i].val / a[i].wei;
    }
    sort(a + 1, a + n + 1, cmp);
    for(register int i = 1; i <= n; i++)
    {
        if(m >= a[i].wei)
        {
            m -= a[i].wei, ans += a[i].val;
        } 
        else
        {
            ans += a[i].vw * m;
            m = 0;
        }
    }
    cout << fixed << setprecision(1) << ans;
    return 0; 
}    
参考程序

猜你喜欢

转载自www.cnblogs.com/kcn999/p/10799480.html