• Test 6.24 T1 购物


    问题描述

    小 C 今天出去购物,商店里总共有 n 种商品,小 C 的钱够买至多 k 个商品。
    小 C 对每种商品都有一个喜爱程度,但如果买了同一种商品很多次,小 C 对这种商品的喜爱程度就会降低。
    具体地说,如果小 C 买了 x 个第 i 种商品,每个第 i 种商品都会让他增加 max(ai−xbi,0)的喜悦值。请你求出小 C 最多能增加多少喜悦值。

    输入格式

    第一行两个正整数 n, k。
    接下来 n 行,每行两个正整数 ai , bi。

    输出格式

    输出一个整数,表示答案。

    样例输入

    2 4
    50 2
    40 1

    样例输出

    171

    数据范围

    对于 50%的数据,n,k ≤1000 。
    对于 100%的数据,n, k, ai ≤10 5 ,bi ≤1000。

    解析

    设第(k)次购买第(i)件商品,那么新购得的商品增加的开心值为(a[i]-k*b[i]),而前面的商品本来可以增加((k-1)*[a[i]-(k-1)*b[i]])的开心值,由于又买了一次,一共减少了((k-1)*b[i])的值,所以,这件商品的贡献为(a[i]-(2k-1)*b[i])。由贪心的思想,用堆维护每次的最大值,每弹出一个值就将对应的商品的新的贡献放进堆中。

    代码

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #define N 100002
    #define int long long
    using namespace std;
    struct con{
    	int a,b,id,cost;
    	bool operator < (const con &x) const{
    		return cost<x.cost;
    	}
    }c[N];
    int n,k,i,cnt[N];
    priority_queue<con> q;
    int read()
    {
    	char c=getchar();
    	int w=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c<='9'&&c>='0'){
    		w=w*10+c-'0';
    		c=getchar();
    	}
    	return w;
    }
    signed main()
    {
    	freopen("buy.in","r",stdin);
    	freopen("buy.out","w",stdout);
    	n=read();k=read();
    	for(i=1;i<=n;i++){
    		c[i].a=read();c[i].b=read();
    		c[i].id=i;cnt[i]++;
    		c[i].cost=c[i].a-c[i].b;
    		q.push(c[i]);
    	}
    	int ans=0;
    	for(i=1;i<=k;i++){
    		con tmp=q.top();
    		q.pop();
    		ans+=tmp.cost;
    		cnt[tmp.id]++;
    		tmp.cost=tmp.a-(2*cnt[tmp.id]-1)*tmp.b;
    		if(tmp.cost<0) tmp.cost=0;
    		q.push(tmp);
    	}
    	cout<<ans<<endl;
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    P.S. 注意long long......

  • 相关阅读:
    filter_input() 函数
    php get_magic_quotes_gpc()函数用法介绍
    echo、print、sprint、sprintf输出
    nl2br() 函数
    chop函数
    in_array 查询数组中是否存在某个值
    SQL技巧
    运算符(一)
    JS数据类型
    JS的基本语法与字面量和变量
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11077952.html
Copyright © 2020-2023  润新知