洛谷 P1023 税收与补贴问题

题目背景

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

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

题目描述

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

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

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

输入输出格式

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

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

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

输入输出样例

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


首先,这题的本质是一个数学题,其思想为设一个未知数x,然后列为无数个的不等式,所有不等式都要求使政府预算的那个价格的总利润大于其他价格的总利润,这样便可以解出x的范围,min<=x<=max,然后根据min和max的正负号来决定输出哪个。

有一点需要注意:题目没有说输入价位是从小到大排序好的,虽然测试数据都是排序好的。

十分暴力的模拟。


#include
#include
#include
using namespace std;
const int N=10005;
int pre,tp=1,jian,price[N],num[N];
double umin=-1e9,umax=1e9;
int main()
{
    scanf("%d",&pre);
    scanf("%d%d",&price[1],&num[1]);
    int x,y;
    while(scanf("%d%d",&x,&y)&&(x!=-1||y!=-1))
    {
        int kxy=-(num[tp]-y)/(x-price[tp]);
        while(price[tp]1]+1;
            num[tp]=num[tp-1]+kxy;
        }
    }
    scanf("%d",&jian);
    int tmpn=num[tp],tmpp=price[tp];
    while(tmpn-jian>0)
    {
        ++tp;
        ++tmpp;
        price[tp]=tmpp;
        tmpn-=jian;
        num[tp]=tmpn;
    }
    int k=-1;
    for(int i=1;i<=tp;i++)
        if(price[i]==pre)
        {
            k=i;
            break;
        }
    if(k<0)
    {
        printf("NO SOLUTION\n");
        return 0;
    }
    for(int i=1;i<=k-1;i++)
        if((double)(num[k]*(price[k]-price[1])-num[i]*(price[i]-price[1]))/(num[i]-num[k])<=umax)
            umax=(double)(num[k]*(price[k]-price[1])-num[i]*(price[i]-price[1]))/(num[i]-num[k]);
    for(int i=k+1;i<=tp;i++)
        if((double)(num[i]*(price[i]-price[1])-num[k]*(price[k]-price[1]))/(num[k]-num[i])>=umin)
            umin=(double)(num[i]*(price[i]-price[1])-num[k]*(price[k]-price[1]))/(num[k]-num[i]);
    if(umin>umax)
        printf("NO SOLUTION\n");
    else if(umin>0)
        printf("%.0f\n",ceil(umin));
    else if(umax<0)
        printf("%.0f\n",floor(umax));
    else
        printf("0\n");
    return 0;
}

你可能感兴趣的:(模拟)