P1023 税收与补贴问题

题目背景

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

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

题目描述

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

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

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

输入输出格式

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

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

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

输入输出样例

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

intput:
315
280 1300
300 1200
310 1100
-1 -1
150
output:-32

input:
4011
1 79990
7999 10
-1 -1
10
output:-20

数据范围看代码吧。
1.这是一个“/\”形函数,随着单价的增加及销售量的减少,利润是这样的曲线图。(模拟)
2.坑点是可能中间两个值会一样,图形变成“/–\”,那么从人的思维角度,更希望单价越大越好。因此代码中带星号的地方有==号,这里应该写的更加严谨一些,但是数据比较弱,就不考虑了。

#include<iostream>
#include<cstdio>
#include<cmath>
#define INF -999999999 
using namespace std;
int p,q,v,a[100001],q1,v1,q2,v2,t,k,tmp,mx1=INF,mx2=INF,rst1,rst2,rx1,rx2; 
void init()//预处理
{
    q1=q,v1=v,a[q]=v;//
    while(1)
    {
        scanf("%d%d",&q2,&v2);
        if(q2==-1 && v2==-1) break;
        k=q1; 
        if(q2-q1>1)
        {
            t=(v1-v2)/(q2-q1);//我们假设价格及销售量都是整数
            tmp=t;
            while(k<q2)
            {
                a[++k]=v1-t;
                t+=tmp; 
            }
        } 
        else {
            a[q2]=v2;
        }
        q1=q2,v1=v2;
    }
    scanf("%d",&t);
    k=q1;
    tmp=t;
    while(a[k]>0)
    {
        a[++k]=v1-t;
        t+=tmp;
    }
//  for(int i=q;i<=k-1;i++)
//      cout<<i<<" "<<a[i]<<endl;
}

int main()
{
//  freopen("test.txt","w",stdout);
    scanf("%d%d%d",&p,&q,&v);
    init();
    int x;
    for(x=0;;x++)//补贴 
    {
        mx1=INF;
        for(int i=q;i<=k-1;i++)
        {
            if((i-q+x)*a[i]>=mx1)
                rst1=i,mx1=(i-q+x)*a[i],rx1=x;
        }
        if(rst1<=p) break; //由于函数曲线得出
    }
    for(x=0;x>=q-k+1;x--)//税收i-q+x>=0(0=<i<=k-1)推算出 
    {
        mx2=INF;
        for(int i=q;i<=k-1;i++)//x>=q-i(i  q  k-1)
        {
            if((i-q+x)*a[i]>=mx2)
                rst2=i,mx2=(i-q+x)*a[i],rx2=x;//最大值的这个数覆盖么? ***
        }
        if(rst2==p) break; 
    }
    if(rst1!=p && rst2!=p) cout<<"NO SOLUTION"<<endl;
    else{
        if(rst1==p && rst2==p) {if(abs(rx1)<abs(rx2)) cout<<rx1<<endl; else cout<<rx2<<endl;}
        else if(rst1==p) cout<<rx1<<endl;
        else cout<<rx2<<endl;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值