【题目描述】
每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给 定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数)
对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)
问题求解:
你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各 种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。
总利润=单位商品利润*销量
单位商品利润=单位商品价格-单位商品成本(-税金 or +补贴)
【输入】
输入的第一行为政府对某种商品的预期价,第二行有两个整数,第一个整数为商品成本, 第二个整数为以成本价销售时的销售量,以下若干行每行都有两个整数,第一个为某价位时 的单价,第二个为此时的销量,以一行-1,-1表示所有已知价位及对应的销量输入完毕,输入的最后一行为一个单独的整数表示在已知的最高单价外每升高一块钱将减少的销量。
【输出】
输出有两种情况:若在政府预期价上能得到最大总利润,则输出一个单独的整数,数的正负表示是补贴还是收税,数的大小表示补贴或收税的金额最小值。若有多解,取绝对值最小的输出。如在政府预期价上不能得到最大总利润,则输出“NO SOLUTION”
【输入样例】
31 28 130 30 120 31 110 -1 -1 15
【输出样例】
4
首先,这题的本质是一个数学题,其思想为设一个未知数x,然后列为无数个的不等式,所有不等式都要求使政府预算的那个价格的总利润大于其他价格的总利润,这样便可以解出x的范围,min<=x<=max,然后根据min和max的正负号来决定输出哪个。
以样例为例,我们要求
(31-28+x)*110>=(28-28+x)*130
(31-28+x)*110>=(29-28+x)*125
(31-28+x)*110>=(30-28+x)*120
(31-28+x)*110>=(32-28+x)*95
1 #include<bits/stdc++.h> 2 using namespace std; 3 int price[10001],num[10001]; 4 int main() 5 { 6 int pre,x,y;cin>>pre; 7 cin>>price[1]>>num[1]; 8 int m=1,jian; 9 double umax=1e9,umin=-1e9;//注意这边是double类型,一开始定义错了还查了很久 10 while(cin>>x>>y&&(x!=-1||y!=-1)) 11 { 12 if(x-price[m]==1) 13 { 14 price[++m]=x; 15 num[m]=y; 16 } 17 else 18 { 19 int kxy=-(num[m]-y)/(x-price[m]);//kxy为中间每差1元减少的销量 20 while(price[m]<x) 21 { 22 price[++m]=price[m-1]+1; 23 num[m]=num[m-1]+kxy; 24 } 25 } 26 } 27 cin>>jian; 28 int tmpn=num[m],tmpp=price[m],k=0; 29 while(tmpn-jian>0) 30 { 31 ++m;++tmpp; 32 price[m]=tmpp; 33 tmpn-=jian; 34 num[m]=tmpn; 35 } 36 for(int i=1;i<=m;i++) 37 if(price[i]==pre) 38 { 39 k=i; 40 break; 41 } 42 if(k==0) 43 { 44 cout<<"NO SOLUTION"; 45 return 0; 46 } 47 for(int i=1;i<k;i++) 48 if((double)((num[k]*(price[k]-price[1])-num[i]*(price[i]-price[1]))/(double)(num[i]-num[k]))<=umax) 49 umax=(double)(num[k]*(price[k]-price[1])-num[i]*(price[i]-price[1]))/(double)(num[i]-num[k]); 50 //(预估价的总利润-某价位上的总利润)/(某价位销量-预估价销量)=应该收的RMB 51 //这个地方不理解的话建议解一下上文列出的不等式 52 for(int i=k+1;i<=m;i++) 53 if((double)((num[i]*(price[i]-price[1])-num[k]*(price[k]-price[1]))/(double)(num[k]-num[i]))>=umin) 54 umin=(double)(num[i]*(price[i]-price[1])-num[k]*(price[k]-price[1]))/(double)(num[k]-num[i]); 55 //(某价位上的总利润-预估价的总利润)/(预估价销量-某价位销量)=应该补贴的RMB 56 if(umax<umin)cout<<"NO SOLUTION";//解集为空 57 else if(umax<0)printf("%.0f",floor(umax));//需要补贴的情况 58 else if(umin>0)printf("%.0f",ceil(umin));//需要收税的情况 59 else cout<<"0";//若不需要补贴或收税 60 return 0; 61 }
//参考:洛谷 P1023 税收与补贴问题 - sdfzrlt的博客 - CSDN博客
https://blog.csdn.net/rlt1296/article/details/52788630
P1023 税收与补贴问题 题解
https://www.luogu.org/problemnew/solution/P1023