[NOIP2000] 提高组 洛谷P1023 税收与补贴问题

题目背景

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

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

题目描述

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

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

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

输入输出格式

输入格式:

 

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

 

输出格式:

 

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

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

 

输入输出样例

输入样例#1:
31
28 130
30 120
31 110
-1  -1
15
输出样例#1:
4

 

求最少需要补贴或者收税的金额,使得所有可能的定价中,只有政府预期的定价带来的收益最高。

设一个未知数x,然后对于每个可能的定价列不等式,所有不等式都要求使政府预算的那个价格的总利润大于其他价格的总利润,这样便可以解出x的范围,在范围内找绝对值最小的那个输出。

例如:

(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

and so on

读入数据后,先根据已知信息,利用线性关系处理出每个定价对应的销量。

解每个不等式,求x的取值范围。

输出答案。

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 const int mxn=12000;
 9 int tar;
10 int w[mxn],a[mxn];//成本,销售量
11 int m,v;
12 int main(){
13     scanf("%d",&tar);
14     int i,j;
15     m=1;
16     int nw,na,lw,la;
17     scanf("%d%d",&w[1],&a[1]);
18     while(1){
19         scanf("%d%d",&nw,&na);
20         if(nw==-1 && na==-1)break;
21         lw=w[m];la=a[m];
22         while(w[m]<nw){
23             m++;
24             w[m]=w[m-1]+1;
25             a[m]=a[m-1]-(la-na)/(nw-lw);
26         }
27     }
28     scanf("%d",&v);
29     while(a[m]-v>0){
30         m++;
31         w[m]=w[m-1]+1;
32         a[m]=a[m-1]-v;
33     }
34 //    for(i=1;i<=m;i++)printf("%d  %d
",w[i],a[i]);//
35     int pos=0;
36     for(i=1;i<=m;i++)if(w[i]==tar){pos=i;break;}
37     if(!pos){printf("NO SOLUTION
");return 0;}
38     double mx=1e8,mini=-1e8;
39     for(i=1;i<pos;i++){
40         double x=( (double)((w[pos]-w[1])*a[pos]-(w[i]-w[1])*a[i])/(double)(a[i]-a[pos]));
41         mx=min(x,mx);
42     }
43     for(i=pos+1;i<=m;i++){
44         double x=( (double)((w[i]-w[1])*a[i]-(w[pos]-w[1])*a[pos])/(double)(a[pos]-a[i]));
45         mini=max(mini,x);
46     }
47     if(mini>mx)printf("NO SOLUTION
");
48     else if(mini>0) printf("%.0f
",ceil(mini));
49     else if(mx<0) printf("%.0f
",floor(mx));
50     else printf("0
");
51     return 0;
52 }
原文地址:https://www.cnblogs.com/SilverNebula/p/5956094.html