厦门理工学院oj 1533-贪吃的学姐

厦门理工学院oj-贪吃的学姐

Description

美丽的静雯学姐有N根棒棒糖,每根棒棒糖有一个价格price(元)和保质期date(还能存放的天数),为了保护牙齿,静雯学姐每天只能吃掉一根棒棒糖。学姐总是尽可能的吃掉最贵的棒棒糖,但是她从不吃过期的棒棒糖!为了避免太多金钱亏损,请问,学姐最多能够吃掉多少价格的棒棒糖。

Input

第一行为一个整数N,表示棒棒糖的总数(1<=N<=100)
接下来是N行,表示N根棒棒糖的相关数据,每行两个整数price和data(1<=price,date<=100),price是棒棒糖的价格,date是该棒棒糖还能存放的天数。N行的price值已经按从高到低排好序。

Output

输出一个整数,表示最多能够吃掉的棒棒糖价格之和

Sample Input

3
20 2
10 1
5 2

Sample Output

30

题解:
我的解题思路为遍历一遍保存价格的数组,把遍历到的糖果设置为保质期的最后一天吃,这样就可以保证能吃到价格最大的糖果的同时保质期之前的时间不会浪费,留给其他的的糖果。如果保质期的最后一天已经被之前价格更大的糖果预定了,就往前搜索,搜索到未被预定的一天,再预定这一天。

代码:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int> candy, date;            //保存价格和日期
    int n, ans = 0;
    bool eat[105] = { false };          //设置预定吃糖果的日期数组为false,如果被预定就设为true
    cin >> n;
    for (int i = 0, a, b; i < n; i++) {
        cin >> a >> b;
        candy.push_back(a);
        date.push_back(b - 1);         //由于日期是从1开始算的,减一存入数组
    }

    for (int i = 0; i < n; i++) {
        int x = date[i];
        if (!eat[x]) {                  //如果保质期最后一天未被预定,预定这一天吃这个糖果
            eat[x] = true;
            ans += candy[i];
        }
        else {                          //如果被预定,则往前遍历寻找未被预定的日期
            while (x > 0) {
                if (!eat[x - 1]) {
                    eat[x - 1] = true;
                    ans += candy[i];
                    break;
                }
                x--;
            }
        }
    }
    cout << ans;
    return 0;
}


这是一道经典的位运算题目,考察对二进制的理解和位运算的熟练程度。 题目描述: 给定一个长度为 $n$ 的数组 $a$,初始时每个数的值都为 $0$。现在有 $m$ 个操作,每个操作为一次询问或修改。 对于询问,给出两个整数 $l,r$,求 $a_l \oplus a_{l+1} \oplus \cdots \oplus a_r$ 的值。 对于修改,给出一个整数 $x$,表示将 $a_x$ 的值加 $1$。 输入格式: 第一行两个整数 $n,m$。 接下来 $m$ 行,每行描述一次操作,格式如下: 1 l r:表示询问区间 $[l,r]$ 的异或和。 2 x:表示将 $a_x$ 的值加 $1$。 输出格式: 对于每个询问操作,输出一个整数表示答案,每个答案占一行。 数据范围: $1 \leq n,m \leq 10^5$,$0 \leq a_i \leq 2^{30}$,$1 \leq l \leq r \leq n$,$1 \leq x \leq n$ 输入样例: 5 5 2 1 2 3 1 2 4 2 2 1 1 5 输出样例: 0 2 解题思路: 对于询问操作,可以利用异或的性质,即 $a \oplus b \oplus a = b$,将 $a_l \oplus a_{l+1} \oplus \cdots \oplus a_r$ 转化为 $(a_1 \oplus \cdots \oplus a_{l-1}) \oplus (a_1 \oplus \cdots \oplus a_r)$,因为两个前缀异或后的结果可以相互抵消,最后的结果即为 $a_1 \oplus \cdots \oplus a_{l-1} \oplus a_1 \oplus \cdots \oplus a_r = a_l \oplus \cdots \oplus a_r$。 对于修改操作,可以将 $a_x$ 对应的二进制数的每一位都分离出来,然后对应位置进行修改即可。由于只有加 $1$ 操作,所以只需将最后一位加 $1$ 即可,其余位不变。 参考代码:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IAS.Trabe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值