zoukankan      html  css  js  c++  java
  • 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;
    }
    View Code
  • 相关阅读:
    C语言内存调试技巧—C语言最大难点揭秘
    include .h 以及.cpp的记录
    VS2010中<无法打开包括文件:“iostream.h”:>错误解决方法
    #include<iostream>与#include<iostream.h>的区别
    VS2013/2012 下无法打开 源 文件“stdafx.h”的解决方法
    【Oracle】Oracle日期格式详解
    【EasyUI】 日期格式化
    【TortoiseGit】TortoiseGit将本地库push到远端
    【Tomcat】解决Eclipse无法添加Tomcat Service问题
    【Tomcat】配置Tomcat
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6411617.html
Copyright © 2011-2022 走看看