P1023 税收与补贴问题
题目背景
每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数)
对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)
题目描述
你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。
总利润=单位商品利润*销量
单位商品利润=单位商品价格 - 单位商品成本 (- 税金 or + 补贴)
输入输出格式
输入格式:输入的第一行为政府对某种商品的预期价,第二行有两个整数,第一个整数为商品成本,第二个整数为以成本价销售时的销售量,以下若干行每行都有两个整数,第一个为某价位时的单价,第二个为此时的销量,以一行-1,-1表示所有已知价位及对应的销量输入完毕,输入的最后一行为一个单独的整数表示在已知的最高单价外每升高一块钱将减少的销量。
输出格式:输出有两种情况:若在政府预期价上能得到最大总利润,则输出一个单独的整数,数的正负表示是补贴还是收税,数的大小表示补贴或收税的金额最小值。若有多解,取绝对值最小的输出。
如在政府预期价上不能得到最大总利润,则输出“NO SOLUTION”。
输入输出样例
31
28 130
30 120
31 110
-1 -1
15
4
说明
所有数字均小于100000
Solution:
又是一道讨厌的暴力模拟题。
直接处理出所有可能的价格情况,然后判断标准价格的购买量,最后就是从小到大暴力枚举补贴和收税的情况,注意一些细节输出就好了。(详见代码)
洛谷数据还是很水的~~我没想到什么好方法判断无解的情况,所以直接忽略了就提交,结果$AC$了。
代码:
#include<bits/stdc++.h> #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define il inline using namespace std; const int N=100005; il int gi(){ int a=0;char x=getchar();bool f=0; while((x<'0'||x>'9')&&x!='-')x=getchar(); if(x=='-')x=getchar(),f=1; while(x>='0'&&x<='9')a=a*10+x-48,x=getchar(); return f?-a:a; } int sdc,sdn,cut,ww,ll,cnt; struct node{ int c,num; bool operator<(const node a)const{return num>a.num;} }a[N]; il void solve(){ int ans=0,p,q,x,y; bool f1=0,f2=0; while(1){ f1=0,f2=0; p=(sdc-a[1].c+ans)*sdn; q=(sdc-a[1].c-ans)*sdn; For(i,1,cnt){ if(a[i].num<=0)break; x=(a[i].c-a[1].c+ans)*a[i].num;y=(a[i].c-a[1].c-ans)*a[i].num; if(x>p)f1=1; if(y>q)f2=1; if(f1&&f2)break; } if(f1&&f2){ans++;continue;} x=a[cnt].c,y=a[cnt].num; while(y>0){ x++;y-=cut; if((x-a[1].c+ans)*y>p)f1=1; if((x-a[1].c-ans)*y>q)f2=1; if(f1&&f2)break; } if(f1&&!f2){cout<<-ans;return;} if(!f1&&f2){cout<<ans;return;} if(!f1&&f2){cout<<ans;return;} ans++; } } int main(){ sdc=gi(); int x,y; while(1){ x=gi(),y=gi(); if(x==-1&&y==-1)break; a[++cnt].c=x,a[cnt].num=y; } cut=gi(); sort(a+1,a+cnt+1); ll=a[2].num-a[1].num; For(i,1,cnt-1) if(a[i+1].c-a[i].c>1) For(j,a[i].c+1,a[i+1].c-1) a[++cnt].c=j, a[cnt].num=a[i].num-(a[i].num-a[i+1].num)/(a[i+1].c-a[i].c)*(j-a[i].c); sort(a+1,a+cnt+1); x=0; For(i,1,cnt)if(a[i].c==sdc){x=1,sdn=a[i].num;break;} if(!x)sdn=a[cnt].num-(sdc-a[cnt].c)*cut; solve(); return 0; }