junior19

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Problem H: 玩具

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 281  Solved: 70

Description

商店有n个玩具,第i个玩具有价格a[i]和快乐值b[i]。有一天,小王来到商店想买一些玩具,商店老板告诉他,如果他买的所有玩具的位置是连续的,那么老板答应小王购买的所有玩具中某一个可以免费。小王接受老板的提议,他现在有零花钱k可以用来买玩具,那么他能获得的最大的快乐值是多少。

Input

第一行给测试总数T(T <= 100),接下来有T组测试数据。
每组测试数据第一行有两个数字n(1 <= n <= 5000)k(0 <= k <= 1000000000)
第二行有n个数字,第i个数字表示第i个玩具的价格a[i](1 <= a[i] <= 1000000)
第三行有n个数字,第i个数字表示第i个玩具的快乐值b[i](1 <= b[i] <= 1000000)

Output

每组测试输出小王能获得的最大快乐值。

Sample Input

3
5 14
1 2 3 4 5
5 4 3 2 1
3 1
100 1000 10000
100 1000 10000
1 0
1000000
1000000

Sample Output

15
10000
1000000

HINT

思路:因为是购买连续的物品,用尺取即可,区间最值从ST表中取出。

# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <vector>
# include <cmath>
# include <cstdlib>
# define INF 0x3f3f3f3f
# define LL long long
using namespace std;
 
const int maxn=5003;
int h[maxn], v[maxn];
int mx[maxn][16];
int n,q;
 
void rmq_init()
{
    int i,j,t;
    for(j=1; j<=n; j++) mx[j][0] = h[j];
    int m = floor(log((double)n) / log(2.0));
    for(i=1; i<=m; i++){
        for(j=1; j<=n; j++)
            {
                t = j+(1<<(i-1));
                if(t<=n) mx[j][i] = max(mx[j][i-1], mx[t][i-1]);
                else mx[j][i] = mx[j][i-1];
            }
    }
}
 
int rmq(int l,int r)
{
    int m = floor(log((double)(r-l+1))/log(2.0));
    int a = max(mx[l][m], mx[r-(1<<m)+1][m]);
    return a;
}

int main()
{
    int t, k;
    scanf("%d",&t);
    while(t--)
    {
        memset(mx, 0, sizeof(mx));
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; ++i)
            scanf("%d",&h[i]);
        rmq_init();
        for(int i=1; i<=n; ++i)
            scanf("%d",&v[i]);
        int l=1, r=1, sum=h[1], tot=v[1], ans=v[1], imax=0;//sum为前缀和,tot为价值。
        while(r <= n)//写的比较丑。
        {
            ans = max(ans , tot);
            if(r == n)
                break;
            if(r+1 <= n && sum+h[r+1]-rmq(l, r+1)<=k)
            {
                ++r;
                tot += v[r];
                sum = sum + h[r];
                ans = max(ans, tot);
            }
            else
            {
                sum -= h[l];
                tot -= v[l];
                ++l;
                while( l< r && sum-rmq(l, r) > k)
                {
                    sum -= h[l];
                    tot -= v[l];
                    ++l;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


posted on 2017-03-19 17:32  junior19  阅读(128)  评论(0编辑  收藏  举报