scau 17967 大师姐唱K的固有结界 分类暴力 + RMQ

由于能放两次,那么分类,

1、连续使用,(这个直接O(n^2)暴力)

2、分开使用。

分开使用的话,首先暴力枚举,用T时间,能从第1个位置,唱到第几首歌,然后剩下的就是从pos + 1, n这个位置,用T时间,最多能省多少体力。这个可以预处理 + rmq搞了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>

#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e3 + 20;
int t[maxn];
int val[maxn];
int T, H, n;
int mx[maxn];
int dp_max[maxn][20];
void init() {
    for (int i = 1; i <= n; ++i) {
        int tot = 0, useTime = 0;
        for (int j = i; j <= n; ++j) {
            useTime += t[j];
            if (useTime > T) break;
            tot += val[j];
        }
        mx[i] = tot;
    }
    for (int i = 1; i <= n; ++i) {
        dp_max[i][0] = mx[i];
    }
    for (int j = 1; j < 20; ++j) {
        for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
            dp_max[i][j] = max(dp_max[i][j - 1], dp_max[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int ask(int be, int en) {
    if (be >  en) return 0;
    int k = (int)log2(en - be + 1.0);
    return max(dp_max[be][k], dp_max[en - (1 << k) + 1][k]);
}
void work() {
    scanf("%d%d%d", &T, &H, &n);
    int hurt = 0;
    for (int i = 1; i <= n; ++i) {
        scanf("%d%d", &t[i], &val[i]);
        hurt += val[i];
    }
    init();
    int mxsave = 0, ans = 0;
    for (int i = 1; i <= n; ++i) {
        int useTime = 0;
        int tot = 0;
        for (int j = i; j <= n; ++j) {
            useTime += t[j];
            if (useTime > 2 * T) {
                break;
            }
            tot += val[j];
        }
        mxsave = max(mxsave, tot);
    }
    ans = H - (hurt - mxsave);
    for (int i = 1; i <= n; ++i) {
        int tot = 0, useTime = 0;
        for (int j = i; j <= n; ++j) {
            useTime += t[j];
            if (useTime > T) break;
            tot += val[j];
            int res = ask(j + 1, n);
            mxsave = max(mxsave, tot + res);
        }
    }
    ans = max(ans, H - (hurt - mxsave));
    ans = max(ans, 0);
    cout << ans << endl;
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}

时间: 2024-10-31 08:16:36

scau 17967 大师姐唱K的固有结界 分类暴力 + RMQ的相关文章

她去看演唱会了,他去唱K了,他们去开房了.都和我无关...因为我要学习。

寂寞. 一个人早起晚睡不难,但在一群晚起早睡的人中早起晚睡不简单. 没人陪你占座,没人陪你背书,没人陪你写作.学习就是孤独的. 食堂,寝室,教室,你就只能去这三个地方 厕所你都要算好时间再去 没人经常短信你,没人经常鼓励你,没人一直关注你 不管是打雷下雨下雹子还是刀子.都要早起前行去学习,你的伙伴会贪睡不去,但不可以是你. 你的同桌室友饭友学友各种友都可以中途打断他们的计划,你不可以!你要学习 你一个人背着书包跑来跑去,你以为很傻很土很幼稚吗? 别人笑,是羡慕,你笑,是自信. 欲望. 想睡懒觉,

K近邻算法——多分类问题

给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类,就把该类输入实例分为这个类. KNN是通过测量不同特征值之间的距离进行分类.它的的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别.K通常是不大于20的整数.KNN算法中,所选择的邻居都是已经正确分类的对象.该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别. 下面通过一个简单的例子说明一下

最小(大)堆找出数组的最小(大)的k项值

//最小堆实现 void MyGlobal::min_heapify(int *a, int* b,int left, int right) { int child = 0; int tmp = 0; int tempb = 0; int parent = left; assert(a != NULL); for (tmp = a[parent],tempb=b[parent]; LEFTSON(parent) <= right; parent = child) { child = LEFTSO

机器学习之路: python k近邻分类器 鸢尾花分类预测

使用python语言 学习k近邻分类器的api 欢迎来到我的git查看源代码: https://github.com/linyi0604/kaggle 1 from sklearn.datasets import load_iris 2 from sklearn.cross_validation import train_test_split 3 from sklearn.preprocessing import StandardScaler 4 from sklearn.neighbors i

ACM-ICPC 2018 青岛赛区现场赛 K. Airdrop &amp;&amp; ZOJ 4068 (暴力)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4068 题意:吃鸡游戏简化为二维平面上有 n 个人 (xi,yi),空投的位置在 (x0,y0),每一秒所有人向靠近空投的位置走一步,四个方向有优先级先后(优先纵坐标),若已经在空投的位置则不变.往空投位置移动过程中,若两个或者更多人在同一点相遇(在空投相遇不算),则他们都死亡.给出空投的纵坐标,询问空投在所有横坐标中最少和最多存活的人数是多少. 题解:在最优情况

HDU2639(01背包第K大)

Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3437    Accepted Submission(s): 1773 Problem Description The title of this problem is familiar,isn't it?yeah,if you had took par

两个数组各个数相加或相乘变成一个矩阵求第K大

input 1<=T<=20 1<=n<=100000,1<=k<=n*n a1 a2 ... an 0<ai<=10000 b1 b2 ... bn 0<bi<=10000 output 第k大的数(包含重复) 做法:类似字符串的编码解码,这里是解码过程,将k解码为对应的01串,把第K大的数看成一个01串,统计出比1000000000000000000000000000000000大的数有多少个,从而确定第一个数是0还是1,然后第二位也是这样,

hdu 5919 主席树(区间不同数的个数 + 区间第k大)

Sequence II Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 849    Accepted Submission(s): 204 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,?

主席树(可持久化线段树) 静态第k大

可持久化数据结构介绍 可持久化数据结构是保存数据结构修改的每一个历史版本,新版本与旧版本相比,修改了某个区域,但是大多数的区域是没有改变的, 所以可以将新版本相对于旧版本未修改的区域指向旧版本的该区域,这样就节省了大量的空间,使得可持久化数据结构的实现成为了可能. 如下图,就是可持久化链表 插入前 插入后 尽可能利用历史版本和当前版本的相同区域来减少空间的开销. 而主席树(可持久化线段树)的原理同样是这样. 有n个数字,  我们将其离散化,那么总有[1,n]个值,如果建一棵线段树,每个结点维护子