洛谷1023 税收与补贴问题 解题报告
洛谷1023 税收与补贴问题
本题地址: http://www.luogu.org/problem/show?pid=1023
题目背景
每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数) 对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)
题目描述
你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。
总利润=单位商品利润*销量
单位商品利润=单位商品价格 - 单位商品成本 (- 税金 or + 补贴)
输入输出格式
输入格式:
输入的第一行为政府对某种商品的预期价,第二行有两个整数,第一个整数为商品成本,第二个整数为以成本价销售时的销售量,以下若干行每行都有两个整数,第一个为某价位时的单价,第二个为此时的销量,以一行-1,-1表示所有已知价位及对应的销量输入完毕,输入的最后一行为一个单独的整数表示在已知的最高单价外每升高一块钱将减少的销量。
输出格式:
输出有两种情况:若在政府预期价上能得到最大总利润,则输出一个单独的整数,数的正负表示是补贴还是收税,数的大小表示补贴或收税的金额最小值。若有多解,取绝对值最小的输出。
如在政府预期价上不能得到最大总利润,则输出“NO SOLUTION”。
输入输出样例
输入样例#1:
31 28 130 30 120 31 110 -1 -1 15
输出样例#1:
4
题解
模拟+穷举
笔者用的是穷举,枚举到以下这两种情况就可停了:
if (价格-成本+补贴(即当前价格的利润)>预期价格的利润)and(当前价格的销量>预期的) then exit(补贴);{因为随着补贴的增加,两者的利润只会相差得更远}
if (价格-成本-税收(即当前价格的利润)>预期价格的利润)and(当前价格的销量<预期的) then exit(税收);{因为随着税收的增加,两者的利润只会相差得更远}
即输出'NO SOLUTION'。
还要注意边界问题,最重要的是细心!
下面附上代码。
代码
- const m=100;
- type point=^node;
- node=record
- price:longint;
- sale:longint;
- next:point;
- end;
- var head,tail,p,q:point;
- pz,sz,pc,sc,si,pi,d,i,k:longint;
- min,max,v:real;
- b1,b2,b:longint;
- begin
- readln(pz);
- readln(pc,sc);
- new(p);head:=p;
- p^.price:=pc;p^.sale:=sc;p^.next:=nil;
- readln(pi,si);
- while pi<>-1 do begin
- for i:=1 to pi-p^.price do begin
- new(q);
- q^.price:=p^.price+1;
- q^.sale:=p^.sale-(p^.sale-si) div (pi-p^.price) ;
- if q^.price=pz then sz:=q^.sale;
- q^.next:=nil;
- p^.next:=q;
- p:=q;
- end;
- readln(pi,si);
- end;
- readln(d);i:=p^.price;si:=p^.sale;
- while si>d do begin
- i:=i+1;
- si:=si-d;
- new(q);
- q^.price:=i;
- q^.sale:=si;
- if q^.price=pz then sz:=q^.sale;
- q^.next:=nil;
- p^.next:=q;
- p:=q;
- end;
- p:=head;max:=-1e20;min:=1e20;
- while p<>nil do begin
- if sz>p^.sale then begin
- v:=((p^.price-pc)*p^.sale-(pz-pc)*sz)/(sz-p^.sale);
- if v>max then max:=v;
- end
- else if sz<p^.sale then begin
- v:=((p^.price-pc)*p^.sale-(pz-pc)*sz)/(sz-p^.sale);
- if v<min then min:=v;
- end;
- p:=p^.next;
- end;
- b1:=trunc(max)-1;
- while b1<max do b1:=b1+1;
- b2:=trunc(min)+1;
- while b2>min do b2:=b2-1;
- if b1<=b2 then begin
- if (b1>=0) and (b2>=0) then writeln(b1)
- else if (b1<0) and (b2<0) then writeln(b2)
- else writeln(0);
- end
- else writeln('NO SOLUTION');
- end.
(本文系笔者原创,未经允许不得转载)