C++ 贪心算法(三)解题报告

前面的几次解题报告分别是经典的背包问题,奶牛的叫声的类似于算法的问题,接下来的解题报告是关于购买东西在规定时间内得到最大价值的题目,这样类型的题也可以转化成超市购买物品、规定时间内完成最多作业等等~
接下来看一道
题目:
A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that is measured as an integral number of time units starting from the moment the sale begins. Each product takes precisely one unit of time for being sold. A selling schedule is an ordered subset of products Sell ≤ Prod such that the selling of each product x∈Sell, according to the ordering of Sell, completes before the deadline dx or just when dx expires. The profit of the selling schedule is Profit(Sell)=Σ x∈Sellpx. An optimal selling schedule is a schedule with a maximum profit.
For example, consider the products Prod={a,b,c,d} with (pa,da)=(50,2), (pb,db)=(10,1), (pc,dc)=(20,2), and (pd,dd)=(30,1). The possible selling schedules are listed in table 1. For instance, the schedule Sell={d,a} shows that the selling of product d starts at time 0 and ends at time 1, while the selling of product a starts at time 1 and ends at time 2. Each of these products is sold by its deadline. Sell is the optimal schedule and its profit is 80.

Write a program that reads sets of products from an input text file and computes the profit of an optimal selling schedule for each set of products.
Input
A set of products starts with an integer 0 <= n <= 10000, which is the number of products in the set, and continues with n pairs pi di of integers, 1 <= pi <= 10000 and 1 <= di <= 10000, that designate the profit and the selling deadline of the i-th product. White spaces can occur freely in input. Input data terminate with an end of file and are guaranteed correct.
Output
For each set of products, the program prints on the standard output the profit of an optimal selling schedule for the set. Each result is printed from the beginning of a separate line.
Sample Input
4 50 2 10 1 20 2 30 1
7 20 1 2 1 10 3 100 2 8 2
5 20 50 10
Sample Output
80
185
Hint
The sample input contains two product sets. The first set encodes the products from table 1. The second set is for 7 products. The profit of an optimal schedule for these products is 185.

依旧呈现中文翻译:
超市有一套Prod of产品在售。它通过截止日期dx销售的每个产品x∈Prod获得利润px,该截止日期dx是从销售开始时起的整数时间单位。每件产品只需一个单位时间即可出售。销售计划是产品的有序子集Sell≤产品,根据销售订单,每个产品x∈Sell的销售在截止日期dx之前或dx到期时完成。销售计划的利润是利润(卖出)= Σx∈Sellpx。最佳销售计划是具有最大利润的计划。
例如,考虑产品Prod = {a,b,c,d},其中(pa,da)=(50,2),(pb,db)=(10,1),(pc,dc)=(20 ,2)和(pd,dd)=(30,1)。表1中列出了可能的销售时间表。例如,时间表Sell = {d,a}表示产品d的销售在时间0开始并在时间1结束,而产品a的销售从时间1开始,在时间2结束。这些产品中的每一个都在截止日期前出售。卖出是最佳时间表,其利润为80。

编写一个程序,从输入文本文件中读取产品集,并计算每组产品的最佳销售计划的利润。
输入
一组产品以整数0 <= n <= 10000开始,这是集合中的产品数量,并且继续n对整数pi di,1 <= pi <= 10000和1 <= di <= 10000,指定第i个产品的利润和销售截止日期。白色空间可以在输入中自由出现。输入数据以文件结尾终止,并保证正确。
产量
对于每组产品,程序在标准输出上打印该组的最佳销售计划的利润。每个结果都是从单独行的开头打印出来的。
样本输入
4 50 2 10 1 20 2 30 1

7 20 1 2 1 10 3 100 2 8 2
5 20 50 10
样本输出
80
185
暗示
示例输入包含两个产品集。第一组对表1中的产品进行编码。第二组用于7种产品。这些产品的最佳时间表利润为185。

直接来看代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct node
{
    int p,d;
}pro[10005];
int isfree[10005];
bool cmp(const node& a,const node& b)
{
    if(a.p==b.p) return a.d>b.d;
    return a.p>b.p;
}
int main()
{
    int n;
    while(cin>>n)
    {
        int mon=0;
        for(int i=0;i<n;i++)
        {
            cin>>pro[i].p>>pro[i].d;
        }
        sort(pro,pro+n,cmp);
        for(int i=0;i<n;i++)
        {
            for(int j=pro[i].d-1;j>=0;j--)
            {
                if(isfree[j]==0)
                {
                    isfree[j]=1;
                    mon+=pro[i].p;
                    break;
                }
            }
        }
        cout<<mon<<endl;
        memset(pro,0,sizeof(node)*n);
        memset(isfree,0,sizeof(isfree));
    }
    return 0;
}

在while循环内部每次使用memset清空,在循环体中先进行价值排序,在相同价值下选时间最短的,isfree的数组是确定已经卖出的产品不会重复卖出,即可写出最终代码。

赠送一道挖坑题:
Lindsay is a shopaholic. Whenever there is a discount of the kind where you can buy three items and only pay for two, she goes completely mad and feels a need to buy all items in the store. You have given up on curing her for this disease, but try to limit its effect on her wallet.

You have realized that the stores coming with these offers are quite selective when it comes to which items you get for free; it is always the cheapest ones. As an example, when your friend comes to the counter with seven items, costing 400, 350, 300, 250, 200, 150, and 100 dollars, she will have to pay 1500 dollars. In this case she got a discount of 250 dollars. You realize that if she goes to the counter three times, she might get a bigger discount. E.g. if she goes with the items that costs 400, 300 and 250, she will get a discount of 250 the first round. The next round she brings the item that costs 150 giving no extra discount, but the third round she takes the last items that costs 350, 200 and 100 giving a discount of an additional 100 dollars, adding up to a total discount of 350.

Your job is to find the maximum discount Lindsay can get.

Input
The first line of input gives the number of test scenarios, 1 <= t <= 20. Each scenario consists of two lines of input. The first gives the number of items Lindsay is buying, 1 <= n <= 20000. The next line gives the prices of these items, 1 <= pi <= 20000.

Output
For each scenario, output one line giving the maximum discount Lindsay can get by selectively choosing which items she brings to the counter at the same time.

Sample Input
1
6
400 100 200 350 300 250

Sample Output
400

林赛是一个购物狂。每当有折扣的时候你可以购买三件商品并且只付两件钱,她会完全疯了,并且觉得需要购买商店里的所有商品。你已经放弃了治疗这种疾病的方法,但试着限制它对钱包的影响。

你已经意识到,随着你免费获得哪些商品,提供这些优惠的商店非常有选择性; 它总是最便宜的。举个例子,当你的朋友带着七件物品来到柜台,花费400,350,300,250,200,150和100美元时,她将需要支付1500美元。在这种情况下,她得到250美元的折扣。你意识到,如果她三次去柜台,她可能会获得更大的折扣。例如,如果她选择400,300和250的物品,她将在第一轮获得250的折扣。下一轮她带来的成本为150,不给予额外折扣,但第三轮她拿最后的成本350,200和100给予额外100美元的折扣,总计折扣350。

你的工作是找到Lindsay可以获得的最大折扣。

输入
第一行输入给出了测试场景的数量,1 <= t <= 20.每个场景由两行输入组成。第一个给出Lindsay购买的商品数量,1 <= n <= 20000.下一行给出这些商品的价格,1 <= p i <= 20000。

产量
对于每个场景,输出一行给出最大折扣Lindsay可以通过选择性地选择她同时带到柜台的项目来获得。

样本输入
1
6
400 100 200 350 300 250

样本输出
400

来一个代码:

#include<iostream>
#include<algorithm>
#include<cmath>
bool cmp(int &a,int &b)
{
	return a>b;
}
using namespace std;
int main()
{
	int m,n,i,j,a[20001],sum;
	cin>>m;
	while(m--)
	{
		sum=0;
		cin>>n;
		for(i=0;i<n;++i)
		{
			cin>>a[i];
		}
		sort(a,a+n,cmp);
		for(i=2;i<n;i+=3)
		{
			sum+=a[i];
		}
		cout<<sum<<endl;
	}
	return 0;
}

这道题十分简单,最后使用一个重复+3的算法即可得出答案。

发布了90 篇原创文章 · 获赞 15 · 访问量 3161

猜你喜欢

转载自blog.csdn.net/qq_43656233/article/details/88700450