SGU_311 Ice-cream Tycoon(线段树)

Ice-cream Tycoon

Time limit per test: 0.5 second(s)
Memory limit: 65536 kilobytes
Problem Description

You’ve recently started an ice-cream business in a local school. During a day you have many suppliers delivering the ice-cream for you, and many students buying it from you. You are not allowed to set the prices, as you are told the price for each piece of ice-cream by the suppliers.

The day is described with a sequence of queries. Each query can be either ARRIVE n c, meaning that a supplier has delivered n pieces of ice-cream priced c each to you, or BUY n t, meaning that a student wants to buy n pieces of ice-cream, having a total of t money. The latter is processed as follows: in case n cheapest pieces of ice-cream you have cost no more than t (together), you sell those n cheapest pieces to the student; in case they cost more, she gets nothing. You start the day with no ice-cream.

For each student, output HAPPY if she gets her ice-cream, and UNHAPPYif she doesn’t.

Input

The input file contains between 1 and 105 queries (inclusive), each on a separate line. The queries are formatted as described above, either ARRIVE n c or BUY n t, 1 ≤ n, c ≤ 106, 1 ≤ t ≤ 1012.

Output

For each BUY-query output one line, containing either the word HAPPY or the word UNHAPPY (answers should be in the same order as the corresponding queries).

Sample Input

ARRIVE 1 1
ARRIVE 10 200
BUY 5 900
BUY 5 900
BUY 5 1000

Sample Output

HAPPY
UNHAPPY
HAPPY

题意

有一个冰激凌店,冰激凌店的物品价格无法自由定价,有两种事件:

  • 进货 ,有n个冰激凌到达店里,每个进价为c
  • 售卖,有人来买n个冰激凌,共付t元,店员会把n个进价最便宜的冰激凌拿出来,如果进价总和超过t元,则不售卖,否则就卖给他。

求每个购买冰激凌的人能否买到自己需要的冰激凌。

题解:

题目的两种操作,主要有查询和更改两种操作,需要快速计算出最小的n个物品的权值和。可以利用线段树或平衡树来维护。对于更新操作,直接插入即可,物品售出后,n个物品的删除操作,可以按价格删除,每次删除价格最少的物品,这样最多把加入进来的物品全部删除,复杂度是可以接受的。
使用线段树可以先读入所有输入,然后对数据离散化,线段树维护区间和 、 物品数量。 (PS:其实不离散化也是可以的,毕竟价格最高1e6)。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctype.h>
#include<cstring>
#include<queue>
#include<stack>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-6
 
using namespace std;
typedef long long LL;   
typedef pair<LL, int> P;
const int maxn = 1000100;
const int mod = 1000000007;
LL sum[maxn*3], a[maxn], p[maxn*3];
void creat(int l, int r, int k);
LL queryid(int l, int r, int k);
LL querysum(int l, int r, int x, int k);
void Update(int l, int r, int x, int y, int k);

int main()
{
    int n, m=1000000, i, j;
    LL t;
    char str[30];
    creat(1, m, 1);
    while(~scanf("%s %d %I64d", str, &n, &t))
    {
        if(str[0] == 'A'){
            a[t] += n;
            Update(1, m, t, n, 1); 
        }
        else{
            if(n > p[1])
                printf("UNHAPPY\n");
            else{
                LL sum = querysum(1, m, n, 1);
                if(sum <= t){
                    printf("HAPPY\n");
                    while(n)
                    {
                        int id = queryid(1, m, 1);
                        LL x = min((LL)n, a[id]);
                        Update(1, m, id, -x, 1);
                        a[id] -= x, n -= x;
                    }
                }
                else
                    printf("UNHAPPY\n");
            }
        }
    }
    return 0;
}

void creat(int l, int r, int k)
{
    p[k] = 0, sum[k] = 0;
    if(l == r)return;
    int mid=(l+r)/2;
    creat(l, mid, 2*k);
    creat(mid+1, r, 2*k+1);
}

void Update(int l, int r, int x, int y, int k)
{
    if(l == r){
        p[k] += y;
        sum[k] += (LL)y*l;
        return;
    }
    int mid = (l+r)/2;
    if(x<=mid)Update(l, mid, x, y, 2*k);
    else Update(mid+1, r, x, y, 2*k+1);
    p[k] = p[2*k]+p[2*k+1];
    sum[k] = sum[2*k]+sum[2*k+1];
}

LL querysum(int l, int r, int x, int k)
{
    if(l == r)return (LL)l*x;
    int mid = (l+r)/2;
    if(x<=p[2*k])return querysum(l, mid, x, 2*k);
    else return sum[2*k]+querysum(mid+1, r, x-p[2*k], 2*k+1);
}

LL queryid(int l, int r, int k)
{
    if(l == r)return l;
    int mid = (l+r)/2;
    if(p[2*k])return queryid(l, mid, 2*k);
    else return queryid(mid+1, r, 2*k+1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Matlab中的优化工具箱来求解该最大化问题。具体步骤如下: 1. 定义目标函数:将最大化问题转化为最小化问题,即将目标函数乘以-1。在Matlab中可以定义一个匿名函数来表示目标函数。 ```matlab f = @(x) -sum(Z(SGU)*C_1*Task.*L_k.*log(x(1:N))) + C_2*sum(x(N+1:end).^2/2); ``` 其中,x为优化变量,前N个元素为p_sm,后M个元素为q_sm。 2. 定义约束条件:根据题目中的约束条件,可以将p_sm限制在[0,1]的范围内。在Matlab中可以使用ineqconstr函数定义不等式约束条件。 ```matlab A = []; b = []; Aeq = []; beq = []; lb = zeros(N+M,1); ub = ones(N,1); nonlcon = @(x) []; ``` 其中,A、b、Aeq、beq、lb和ub分别表示线性等式约束、线性不等式约束、非线性等式约束、非线性不等式约束、变量下界和变量上界。nonlcon表示非线性约束条件,在本问题中为空。 3. 求解最小化问题:使用Matlab中的fmincon函数求解最小化问题。 ```matlab x0 = rand(N+M,1); [x,fval,exitflag,output] = fmincon(f,x0,A,b,Aeq,beq,lb,ub,nonlcon); ``` 其中,x0为优化变量的初始值。fval为目标函数的最小值。exitflag表示求解器的退出标志,0表示收敛,其它值表示未收敛。output为求解过程的详细信息。 4. 计算最大化问题的解:将目标函数的最小值乘以-1得到最大化问题的最优解。 ```matlab max_fval = -fval; max_p_sm = x(1:N); max_q_sm = x(N+1:end); ``` 其中,max_p_sm和max_q_sm分别为最优解中的p_sm和q_sm。 以上就是使用Matlab求解该最大化问题的基本步骤。需要注意的是,在实际应用中,还需要根据具体情况进行调试和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值