protagonist

全连

11374: 全连

时间限制: 1 Sec  内存限制: 256 MB
提交: 15  解决: 3
[提交] [状态] [命题人:admin]

题目描述

还记得若干年前那段互相比较《克罗地亚狂想曲》的分数的日子吗?
E.Space 喜欢打音游。
但是他技术不好,总是拿不到全连(Full Combo)。
现在他面前有一份乐谱,乐谱的其中一段有 n 个连续的单键音符。
相邻两个音符的到来时间均相等,我们可以认为第 i 个音符会在第 i 个时刻到来。
点击一个音符,E.Space 需要一段准备时间来进行移动手指之类的操作。由于音符的位置和周围情况不同,点击每个音符的准备时间也不同。
在一个音符的准备时间内,E.Space 没法做到去点击其它音符,但是不同音符的准备时间范围可以互相重叠。形式化地,令第 i 个音符的准备时间为 ti个单位时间,那么如果 E.Space 选择去点击第 i 个音符,那么他就没法点击所有到来时刻在 (i−ti ,i+ti)中的音符。
为了获得更高的分数,E.Space 还计算了每个音符的性价比。一个音符的性价比等于点击这个音符得到的分数除以 E.Space 点击它所需要的准备时间。
E.Space 就不指望全连了,他只是想让你帮他计算一下他最多可以得到多少分数。

 

输入

第一行一个正整数 n 。
第二行 n 个正整数,第 i 个正整数表示 ti。
第三行 n 个正整数,第 i 个正整数表示第 i 个音符的性价比 ai。

 

输出

一行一个正整数,表示 E.Space 可能达到的最高分数。

 

样例输入

5
2 3 2 1 2
3 1 2 9 4

样例输出

18

 

提示

E.Space 可以选择点击第 1,3,5 个音符,分数为 2×3+2×2+2×4=18 。

保证 ti≤n,ai≤109

#include<bits/stdc++.h>
#define REP(i, a, b) for(int i = (a); i <= (b); ++ i)
#define REP(j, a, b) for(int j = (a); j <= (b); ++ j)
#define PER(i, a, b) for(int i = (a); i >= (b); -- i)
using namespace std;
const int maxn = 1e6 + 5;
template <class T>
inline void rd(T &ret) {
    char c;
    ret = 0;
    while ((c = getchar()) < '0' || c > '9');
    while (c >= '0' && c <= '9') {
        ret = ret * 10 + (c - '0'), c = getchar();
    }
}
typedef long long ll;
int t[maxn];
ll ans, dp[maxn], cur, p[maxn*4];
struct node {
    int now;
    bool operator<(const node &tmp)const {
        return now + t[now] > tmp.now + t[tmp.now];
    }
};
priority_queue<node>q;
void update(int root, int l, int r, int cur, ll val) {
        if (l == r) {
            p[root] = val;
            //cout<<p[root]<<endl;
            return;
        }
        int mid = l + r >> 1;
        if (cur <= mid)update(root << 1, l, mid, cur, val);
        else update(root << 1 | 1, mid + 1, r, cur, val);
        p[root] = max(p[root << 1], p[root << 1 | 1]);
        return;
}
long long query(int root, int l, int r, int ql, int qr) {
        if (ql > qr)return 0;
        if (ql <= l && qr >= r)return p[root];
        int mid = l + r >> 1;
        if (mid < ql)return query(root << 1 | 1, mid + 1, r, ql, qr);
        if (mid >= qr)return query(root << 1, l, mid, ql, qr);
        return max(query(root<<1,l,mid,ql,qr),query(root<<1|1,mid+1,r,ql,qr));
}
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)cin >> t[i];
    for (int i = 1; i <= n; i++) {
          cin >> cur;
          dp[i] = cur * t[i];
          while (!q.empty()) {
              node tmp = q.top();
              if (tmp.now + t[tmp.now] > i)break;
              q.pop();
              update(1,1,n,tmp.now,dp[tmp.now]);
          }
          //cout<<"******"<<endl;
          dp[i] += query(1,1,n,1,i-t[i]);
          ans = max(ans, dp[i]);
          q.push(node{ i });
    }
    cout << ans << endl;
    return 0;
}

 

posted @ 2019-03-18 00:04  czy-power  阅读(275)  评论(0编辑  收藏  举报