洛谷P1023 税收与补贴问题
题目背景
每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数)
对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)
题目描述
你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。
总利润=单位商品利润*销量
单位商品利润=单位商品价格 - 单位商品成本 (- 税金 or + 补贴)
输入输出格式
输入格式:
输入的第一行为政府对某种商品的预期价,第二行有两个整数,第一个整数为商品成本,第二个整数为以成本价销售时的销售量,以下若干行每行都有两个整数,第一个为某价位时的单价,第二个为此时的销量,以一行-1,-1表示所有已知价位及对应的销量输入完毕,输入的最后一行为一个单独的整数表示在已知的最高单价外每升高一块钱将减少的销量。
输出格式:
输出有两种情况:若在政府预期价上能得到最大总利润,则输出一个单独的整数,数的正负表示是补贴还是收税,数的大小表示补贴或收税的金额最小值。若有多解,取绝对值最小的输出。
如在政府预期价上不能得到最大总利润,则输出“NO SOLUTION”。
输入输出样例
输入样例#1:
31 28 130 30 120 31 110 -1 -1 15
输出样例#1:
4
/* 首先表示题目很难理解,先来解释一下题意 就从样例开始分析。 输入是: 31 28 130 30 120 31 110 -1 -1 15 意思就是政府预期价是31元。成本28元,按成本销售的时候可以买130件产品。 每个卖30元的时候可以卖120个, 每个卖31元(输入的最高价位)的时候可以卖110个, 每个卖32元的时候可以卖:110-15=95个。 每个卖33元的时候可以卖:110-15-15=80个。 每个卖34元的时候可以卖:110-15-15-15=65个。 ... 因为“相邻价位之间的销量变化是均匀的”,因此28元卖130个,30元卖120个就可以知道 29元卖125个(平均每元减少的销量是(130-120) div (30-28)=5) 输出是4,我们来解释一下为什么是4。 4代表补贴是4元,所以: 在卖28元的时候,总利润是:(28-28+4)*130=520元, 在卖29元的时候,总利润是:(29-28+4)*125=625元, 在卖30元的时候,总利润是:(30-28+4)*120=720元, 在卖31的时候,总利润是:(31-28+4)*110=770元, 在卖32元的时候,总利润是:(32-28+4)*95=760元, ... 在卖38元的时候,总利润是:(38-28+4)*5=70元, 显然可能的价位就是28~38了。(不能低于成本,卖39的时候销售量就是负数了) 可以看出,现在卖31元最划算,所以人们都愿意卖31元,这样一来不就达到政府的目的了吗!! 而当补贴是0,1,2,3的时候卖31元并不是最划算的,政府的目的达不到,你当然就没有分啦! 所以我就直接枚举答案 */ #include<iostream> #include<cstdio> using namespace std; int goal,org,orgn,k,a1,a2,a3; double b1,b2,b3; bool check(int x){ double c1=(a1-org+x)*b1; double c2=(a2-org+x)*b2; double c3=(a3-org+x)*b3; if(c2>=c1&&c2>=c3)return 1; return 0; } int main(){ //freopen("Cola.txt","r",stdin); scanf("%d%d%d",&goal,&org,&orgn); a1=goal-1,a2=goal,a3=goal+1; int x,y,prex=org,prey=orgn; while(1){ scanf("%d%d",&x,&y); if(x==-1&&y==-1)break; if(a1==x)b1=y; else if(a1<x&&a1>prex)b1=prey+((double)(y-prey)/(double)(x-prex))*(a1-prex); if(a2==x)b2=y; else if(a2<x&&a2>prex)b2=prey+((double)(y-prey)/(double)(x-prex))*(a2-prex); if(a3==x)b3=y; else if(a3<x&&a3>prex)b3=prey+((double)(y-prey)/(double)(x-prex))*(a3-prex); prex=x;prey=y; } scanf("%d",&k); if(a1>prex)b1=prey-(a1-prex)*k; if(a2>prex)b2=prey-(a2-prex)*k; if(a3>prex)b3=prey-(a3-prex)*k; for(int i=0;i<=500000;i++){ x=i; if(check(x)){ printf("%d",x); return 0; } x=-i; if(check(x)){ printf("%d",x); return 0; } } printf("NO SOLUTION"); return 0; }