列表

详情


NC16750. [NOIP2000]税收与补贴问题

描述

每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数)
对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)
你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。
总利润 = 单位商品利润 * 销量 
单位商品利润 = 单位商品价格 – 单位商品成本(– 税金  or  + 补贴)

输入描述

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

输出描述

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

示例1

输入:

31
28 130
30 120
31 110
-1  -1
15

输出:

4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0)(g++7.5.0) 解法, 执行用时: 4ms, 内存消耗: 524K, 提交时间: 2022-09-12 14:13:14

#include <iostream>
#include <cmath>
using namespace std;
int a[100010][3];//用于存放价格和销量的数组
int main()
{
	int i = 1, j = 1, k, expect, down, max, temp, cha, xl, num, s, price, p;
	cin >> expect;//读入预期价
	while (cin >> a[i][1] >> a[i][2] && a[i][1] != -1 && a[i][2] != -1)//如果输入的两个数不是-1,-1
	{
		i++;//循环变量i++
		if (i > 2 && a[i - 1][1] - a[i - 2][1] > 1)//如果两个价格之间差大于一
		{
			i--;//回到上一个读入的销量
			cha = (a[i - 1][2] - a[i][2]) / (a[i][1] - a[i - 1][1]);//求出每次销量减少多少:销量差/价格差
			temp = a[i][1];//记录下价格
			for (j = a[i - 1][1] + 1; j <= temp; j++)//按价格递增顺序依次写入
			{
				a[i][1] = j;//写入价格
				a[i][2] = a[i - 1][2] - cha;//按销量差写入销量
				i++;
			}
		}
	}
	cin >> down;//输入超过最大价格之后每次销量降低多少
	i--;//因为上面的while循环最后有i++所以用i--抵消……
	xl = a[i][2];//记录目前的销量
	while (xl > 0)
	{
		if (xl - down < 0)break;//如销量小于零则退出
		else//否则
		{
			xl -= down;
			i++;
			a[i][1] = a[i - 1][1] + 1;
			a[i][2] = xl;
		}
	}
	for (j = 1; j <= 10000; j++)
	{
		max = -99999;
		for (k = 1; k <= i; k++)
		{
			num = (a[k][1] - a[1][1] + j) * a[k][2];
			if (num >= max)
			{
				max = num;
				price = a[k][1];
				p = 1;
			}
		}
		if (price == expect) { cout << j * p; return 0; }
			max = -99999;
		for (k = 1; k <= i; k++)
		{
			num = (a[k][1] - a[1][1] - j) * a[k][2];
			if (num >= max)
			{
				max = num;
				price = a[k][1];
				p = -1;
			}
		}
		if (price == expect) { cout << j * p; return 0; }
	}
}

C++14(g++5.4) 解法, 执行用时: 12ms, 内存消耗: 604K, 提交时间: 2019-09-09 14:01:44

#include <bits/stdc++.h>
using namespace std;

const int maxn = 100000;
int sale[maxn];
int earn[maxn];
int main() {
	int expect; cin >> expect;
    int t1, t2; cin >> t1 >> t2;
    sale[t1] = t2;
    int cost = t1;
    int last_t1 = t1;
    while (cin >> t1 >> t2 && t1 != -1) {
        sale[t1] = t2;
        int k = last_t1 + 1;
        while (k != t1) {
            sale[k] = sale[last_t1] + (sale[t1] - sale[last_t1] ) * (k - last_t1) / (t1 - last_t1);
            k++;
        }
        last_t1 = t1;
    }
    int dec; cin >> dec;
    while (sale[last_t1] > 0) {
        last_t1++;
        sale[last_t1] = sale[last_t1 - 1] - dec;
    }

    int k = 0;
    while (true) {
        for (int i = 0; i < last_t1; i++) {
            earn[i] = (i + k - cost) * sale[i];
            if (earn[i] <= 0) continue;
        }
        if (*max_element(earn, earn + maxn) == earn[expect] ){//                && count(earn, earn + maxn, earn[expect]) == 1) {
            cout << k << endl;
            return 0;
        }
        for (int i = 0; i < last_t1; i++) {    //
            earn[i] = (i - k - cost) * sale[i];
        }
         if (*max_element(earn, earn + maxn) == earn[expect] ){//} && count(earn, earn + maxn, earn[expect]) == 1) {
            cout << -k << endl;
            return 0;
        }
        k++;
    }
}

C++ 解法, 执行用时: 4ms, 内存消耗: 400K, 提交时间: 2021-06-18 17:59:46

#include <bits/stdc++.h>
int expect, cost[100000], sale[100000], len, c, s, d, maxpos, maxneg;
int main() {
  scanf("%d%d%d", &expect, cost, sale);
  while (~scanf("%d%d", &c, &s)&&~c&&~s) {
    d=(s-sale[len])/(c-cost[len]);
    for (int i=cost[len]+1; i<=c; i++, len++) {
      cost[len+1]=i;
      sale[len+1]=sale[len]+d;
    }
  }
  scanf("%d", &d); d=-d;
  for (int i=cost[len]+1; sale[len]+d>0; i++, len++) {
    cost[len+1]=i;
    sale[len+1]=sale[len]+d;
  }
  for (int i=1; ; i++) {
    maxpos=maxneg=0;
    for (int j=1; j<=len; j++) {
      if (sale[j]*(cost[j]-cost[0]+i)>=sale[maxpos]*(cost[maxpos]-cost[0]+i))
        maxpos=j;
      if (sale[j]*(cost[j]-cost[0]-i)>=sale[maxneg]*(cost[maxneg]-cost[0]-i))
        maxneg=j;
    }
    if (cost[maxpos]==expect) {
      printf("%d", i); break;
    } else if (cost[maxneg]==expect) {
      printf("%d", -i); break;
    }
  }
  return 0;
}

上一题