PTA |1020 月饼 贪心

288 阅读4分钟

PTA | 程序设计类实验辅助教学平台 (pintia.cn)

贪心策略

这道题用贪心思想来做比较简单,就是我们优先单价最高的月饼种类,先把单价最高的月饼库存量存给累加起来,直到发现满足了 市场最大需求量,那么就把它的单价*市场需求量 就求出了最大收益策略

如果发现最高的月饼库存量不满足 市场最大需求量 ,那么就把 单价第二高月饼库存量 累加起来,看是否满足 市场最大需求量,以此类推。

因此我们需要按单价进行一个降序排序

我们可以用c++的sort()或者用c的qsort()都可以:

sort()

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 1001;  // 不超过1000个月饼种类

typedef struct {
    double stock;     // 库存
    double sumprice;  // 每款月饼总价
    double price;     // 每款月饼单价
} mooncake;

bool cmp(mooncake c1, mooncake c2) {
    return c1.price > c2.price;  // 按单价降序返回
}

int main() {
    vector<mooncake> v(N);
    double total = 0;
    int n, max_demand; // 月饼种类个数,市场最大需求量
    cin >> n >> max_demand; // 读取月饼种类个数和市场最大需求量

    // 月饼各种类库存
    for (int i = 0; i < n; i++) cin >> v[i].stock;
    // 月饼各种类总价
    for (int i = 0; i < n; i++) cin >> v[i].sumprice;
    // 月饼各种类单价
    for (int i = 0; i < n; i++) v[i].price = v[i].sumprice / v[i].stock;
    // 按单价降序排序
    sort(v.begin(), v.begin()+n , cmp);

    for (int i = 0; i < n && max_demand > 0; i++) {
        if (v[i].stock <= max_demand) {   // 某款月饼库存比需求量低。
            total += v[i].sumprice;       // 这款月饼总价全部放入销售额。
            max_demand -= v[i].stock;      // 需求量扣除这款月饼的库存。
        } else {                           // 某款月饼的库存满足了需求量。
            total += max_demand * v[i].price;  // 销售额 = 需求量 * 这款月饼单价。
            max_demand = 0;                     // 需求置零,退出循环。
        }
    }

    printf("%.2f\n", total);

    return 0;
}

qsort()

#include<iostream>
#include<algorithm>
using namespace std;

const int N = 1001;  // 不超过1000个月饼种类

typedef struct {
    float stock;     // 库存
    float sumprice;  // 每款月饼总价
    float price;     // 每款月饼单价
} mooncake;

int cmp(const void *a, const void *b) {
    mooncake c1 = *(mooncake *)a; //将指针a强制转化为mooncake结构体类型。
    mooncake c2 = *(mooncake *)b;
    return c2.price > c1.price;  // 按单价降序返回
}

int main() {
     mooncake v[N];  
     float total = 0;
    int n, max_demand; // 月饼种类个数,市场最大需求量
    cin >> n >> max_demand; // 读取月饼种类个数和市场最大需求量
 
    //月饼各种类库存
    for (int i = 0; i < n; i++) cin >> v[i].stock ;
    //月饼各种类总价
     for (int i = 0; i < n; i++) cin>> v[i].sumprice;
    //月饼各种类单价
  for (int i = 0; i < n; i++) v[i].price = v[i].sumprice/v[i].stock;
  //按单价降序排序
  qsort (v, n,sizeof v[0], cmp );    //sizeof(cake[0])也行。

   
    for (int i = 0; i < n && max_demand > 0; i++) {
        if (v[i].stock <= max_demand) {   //某款月饼库存比需求量低。
            total += v[i].sumprice;       //这款月饼总价全部放入销售额。
            max_demand -= v[i].stock;      //需求量扣除这款月饼的库存。
        } else {                           //某款月饼的库存满足了需求量。
            total += max_demand * v[i].price;  //销售额 = 需求量 * 这款月饼单价。
            max_demand = 0;                     //需求置零,退出循环。
        }
    }

    printf("%.2f\n", total);

    return 0;
}

利用循环找到单价最高的月饼出售,直到满足市场最大需求量

#include<iostream>
using namespace std;
const int N=1010;


int main()
{

  float total;
    int n,max_demand; // 月饼种类个数,市场最大需求量
    cin >> n >> max_demand; // 读取月饼种类个数和市场最大需求量
    
  float sumprice[N],stock[N];  //各种月饼总价,各种月饼库存量
    
   
     for (int i = 0; i < n; i++)
        cin >> stock[i];
    for (int i = 0; i < n; i++)
        cin >> sumprice[i];

    while(max_demand>0) //当最大收益不为0的时候
    {
      int  max=0;  //索引  用来标记最大单价 最大库存量  最大总价
        // 寻找具有最大单价的月饼
        for(int i=0;i<n;i++)
        {
            //如果当前月饼单价 大于  最高月饼单价时
            if((sumprice[i]/stock[i])>(sumprice[max]/stock[max]))
            max=i;  //更新当前月饼单价为最大月饼单价
        }

        // 如果市场需求量大于月饼的最大库存量
        if(max_demand>stock[max])
        {
            
            total+=sumprice[max];      //累加总价
            max_demand-=stock[max];    //减少市场需求量
            sumprice[max]=0;           //把最高总价置为0
        }//市场需求量 
        
        else   //月饼的最大库存量不满足于 
        {
            //最大收益=最大需求量*(最大单价)
           total += max_demand * (sumprice[max] / stock[max]);
            max_demand=0;// 市场需求量已满足
        }
    }
    printf("%.2f\n",total);
        return 0;
}