洛谷 普及组 P1023 税收与补贴问题

题目背景

每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数)

对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)

题目描述

你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。

总利润 = 单位商品利润 × 销量

单位商品利润 = 单位商品价格 - 单位商品成本 (- 税金 or + 补贴)

输入格式

输入的第一行为政府对某种商品的预期价,第二行有两个整数,第一个整数为商品成本,第二个整数为以成本价销售时的销售量,以下若干行每行都有两个整数,第一个为某价位时的单价,第二个为此时的销量,以一行−1,−1表示所有已知价位及对应的销量输入完毕,输入的最后一行为一个单独的整数表示在已知的最高单价外每升高一块钱将减少的销量。

输出格式

输出有两种情况:若在政府预期价上能得到最大总利润,则输出一个单独的整数,数的正负表示是补贴还是收税,数的大小表示补贴或收税的金额最小值。若有多解,取绝对值最小的输出。

如在政府预期价上不能得到最大总利润,则输出“NO SOLUTION”。

数据范围

所有数字均小于100000

输入输出样例

  输入

31
28 130
30 120
31 110
-1 -1
15

  输出

4

思路

▶用结构体储存价格和对应销量,从成本价开始,价格每次增加1。输入过程若上下两行价格之差不为1则计算这两个价格的价格差和销量差,得到单价销量公差,逐个记录价格及销量。

▶输入完成后,还要记录超过输入的最大价格之后每上涨1元的价格和销量,直到销量≤0不再记录。

▶题目要求的无非是一个数字(税收或补贴,负数表示税收,正数补贴)。此时政府预期价+这个数字的获利 ≥ 其他价格+这个数字的获利。要求输出绝对值最小的,因此这个数字(代码中用sub表示)从1开始遍历,正数负数各遍历一次,某次利润最大时刚好是政府预期价+(或-)sub,则输出sub。

#include<iostream>
using namespace std;
#define maxn 100000
#define INF 0x3f3f3f3f
struct Info{
	int p, n; //价格,销量 
}info[maxn];
int main()
{
	int exp, dn;
	cin >> exp;
	int i = 0;
	while(cin >> info[i].p >> info[i].n ){
		if(info[i].p == -1 && info[i].n == -1) { i--; break;}
		if(i > 0 && info[i].p - info[i-1].p != 1){ //价格差不为1 
			int d = (info[i-1].n-info[i].n) / (info[i].p-info[i-1].p); //计算单价销量公差 
			int sp = info[i-1].p, lp = info[i].p, j;
			for(j = 1; j <= lp - sp; j++){
				info[i-1+j].p = info[i-1].p + j;
				info[i-1+j].n = info[i-1].n - d*j;
			}
			i += j-2;
		}
		i++;
	}
	cin >> dn;
	while(info[i].n - dn > 0){ //销量不为0则一直记录 
		i++;
		info[i].p = info[i-1].p + 1;
		info[i].n = info[i-1].n - dn;
	}
	int sub, profit,  price;
	bool find = false; //作为有否找到一个数字sub使预期价+sub获利最大的标志 
	for(sub = 1; sub < maxn; sub++){
		int max = -INF;
		for(int j = 1; j <= i; j++){
			profit = (info[j].p - info[0].p + sub) * info[j].n;
			if(profit >= max){ max = profit; price = info[j].p;}
		}
		if(price == exp) { find = true; cout << sub << endl; break;}
		max = -INF;
		for(int j = 1; j <= i; j++){			
			profit = (info[j].p - info[0].p - sub) * info[j].n;
			if(profit >= max){ max = profit; price = info[j].p;}
		}
		if(price == exp) { find = true; cout << "-" << sub << endl; break;}
	}
	if(!find) cout << "NO SOLUTION" << endl; 
	return 0;
} 
发布了9 篇原创文章 · 获赞 14 · 访问量 8081

猜你喜欢

转载自blog.csdn.net/qq_45542674/article/details/104182623