P1023 税收与补贴问题
题目背景
每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数)
对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)
题目描述
你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。
总利润=单位商品利润*销量
单位商品利润=单位商品价格 - 单位商品成本 (- 税金 or + 补贴)
输入输出格式
输入格式:输入的第一行为政府对某种商品的预期价,第二行有两个整数,第一个整数为商品成本,第二个整数为以成本价销售时的销售量,以下若干行每行都有两个整数,第一个为某价位时的单价,第二个为此时的销量,以一行-1,-1表示所有已知价位及对应的销量输入完毕,输入的最后一行为一个单独的整数表示在已知的最高单价外每升高一块钱将减少的销量。
输出格式:输出有两种情况:若在政府预期价上能得到最大总利润,则输出一个单独的整数,数的正负表示是补贴还是收税,数的大小表示补贴或收税的金额最小值。若有多解,取绝对值最小的输出。
如在政府预期价上不能得到最大总利润,则输出“NO SOLUTION”。
输入输出样例
3128 13030 12031 110-1 -115
4
Solution
第一次用cnblogs的latex好激动——
题意
第一次给中文题目写题意QwQ,
题意有点恶心。。。
假设销售量y是销售价x的一个函数首先,由于“相邻价位之间销量的变化是线性的”,所以是这是个分段的一次函数样例大概是这样的题目就是求当政府要求交税x元或补贴x元时,
以政府的期望单价售卖得到的利润(用式子表示为$=(期望单价-利润±x)*销售量)$)大于以其他任何价格售卖的利润
求单价对应的销售量
我们设$\ d(i)$表示售价为i的销量
因为已知相邻价位之间售价成线性关系设前一个读入单价为l ,当前单价为 r 那么可得到$\mbox{当售价k在l..r之间时} \frac{d(r)-d(l)}{r-l} = \frac{d(k)-d(l)}{k-l} $$\mbox{可得:} d(k)= (d(r)-d(l))*\frac{k-l}{r-l}+d(l)$于是我们可以计算出对应的d最高价位之后的d,可以直接按照题意求求政府控制量
由题
设w为政府期望价,f为成本,x为控制量,i为其他某个价位则那对于其他所有合法的价位满足$(w-f+x)*d(w)>=(i-f+x)*d(i)$$(w-f)*d(w)+x*d(w)>=(i-f)*d(i)+x*d(i)$$x*d(w)-x*d(i)>=(i-f)*d(i)-(w-f)*d(w)$$x*(d(w)-d(i))>=(i-f)*d(i)-(w-f)*d(w)$设$(d(w)-d(i))=B$ 和$(i-f)*d(i)-(w-f)*d(w)=C$这里考虑一下B的正负性,因为 $w<>i$ 那么不存在$B=0$若$B>0$,$x>=\frac {C}{B}$若$B<0$,$x<=\frac {C}{B}$计算出每个合法价位的关于x的解集然后解不等式组便可得出结论解不等式组
我们假设最后解集在$min<=x<=max$
那么我们在每次$B>0$时候尝试找最大的min(就是把解集的左边界往右缩)在每次$B<0$时候尝试找最小的max(就是把解集的右边界往左缩)最后我们处理结果注意!由于结果可能不是整数,直接trunc不行我们需要对Min向上取整,即$\lfloor max\rfloor$当$min-trunc(min)=0$或$min<0$时,$min=trunc(min)$当$min>0$时,$min=trunc(min)+1$注:$min=0$的情况已经包含在第一种里面啦我们需要max向下取整,即 $\lceil min \rceil$当$max-trunc(max)=0$或$max>0$时,$max=trunc(max)$当$max<0$时,$max=trunc(max)-1$注:$max=0$的情况已经包含在第一种里面啦 如果$min>max$ 很明显无解如果$(min<=0)and(0<=max)$也就是解集中包含0就可以不收税也不补贴输出$0$否则如果$max<0$就是$min<=max<0$,那么输出$max$表示要交税$|max|$如果$max>=0$就是$0<min<=max$,那么输出$min$表示要补贴$min$
At Last
Q1: d为什么开100000啊?
A1: 其实我也不知道——题目也没给出来,只能看题解啦 Q2: 泥怎么不用排序啊?A2: 玄学。。。Codes
1 uses math; 2 var 3 k,i:longint; 4 w,sell,l,r,cb,b,c,cut:longint; 5 min1,max1:Extended; 6 minn,maxx:longint; 7 8 d:array[1..100000] of longint; 9 t:Boolean;10 11 procedure pr(s:string);12 begin13 writeln(s);14 close(input); close(output);15 halt;16 end;17 18 begin19 // assign(input,'t.in'); assign(output,'t.out');20 reset(input); rewrite(output);21 22 readln(w);23 l:=0;24 while true do25 begin26 readln(r,sell);27 if r=-1 then break;28 d[r]:=sell;29 if l<>0 then30 for k:= l+1 to r-1 do //计算相邻价位之间的d31 d[k]:=(d[r]-d[l])*(k-l) div (r-l)+d[l]32 else cb:=r;33 l:=r;34 end;35 36 readln(cut);37 r:=l+1;//计算高于最高价位的d38 while d[r-1]>=0 do39 begin40 d[r]:=d[r-1]-cut;41 inc(r);42 end;43 r:=r-1;44 45 min1:=-maxlongint;46 max1:=maxlongint;47 48 for i:= cb to r do //计算每个合法价位的不等式解49 if (i<>w) and (d[i]>0) then50 begin51 B:=d[w]-d[i];52 C:=(i-cb)*d[i]-(w-cb)*d[w];53 if B>0 then min1:=max(C/B,min1)54 else max1:=min(C/B,max1);55 end;56 57 //对Min向上取整,对max向下取整58 if (min1-trunc(min1)=0) or (min1<0) then minn:=trunc(min1)59 else minn:=trunc(min1)+1;60 if (max1-trunc(max1)=0) or (max1>0) then maxx:=trunc(max1)61 else maxx:=trunc(max1)-1;62 63 if minn>maxx then pr('NO SOLUTION');64 if (minn<=0) and (0<=maxx) then pr('0');65 if maxx<0 then writeln(maxx) else writeln(minn);66 67 close(input); close(output);68 end.