zstu 校赛 4273 (双指针+单调队列)

来源:互联网 发布:mac与pc共享连接失败 编辑:程序博客网 时间:2024/06/05 11:30


4273: 玩具

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 744  Solved: 145

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

35 141 2 3 4 55 4 3 2 13 1100 1000 10000100 1000 100001 010000001000000

Sample Output

15100001000000

解题思路:

这题暴力也可以过。

但是正规的解法是用双指针去枚举可能的区间,用单调队列维护区间最大值。

虽然这两种技能我都会,但是赛时也没想到,直接暴力过了,还是不太熟练吧。


代码:

#include <bits/stdc++.h>using namespace std;int inde[5006];int a[5006];int b[5006];int sum[5006];int hap[5006];int main(){    int ha, ans, head, tail, i, j, ed, t, n, k;    cin>>t;    while(t--)    {        scanf("%d%d", &n, &k);        for(i=1; i<=n; i++)        {            scanf("%d", &a[i]);            sum[i]=0;            sum[i]+=(sum[i-1]+a[i]);        }        ha=0;        for(i=1; i<=n; i++)        {            scanf("%d", &b[i]);         }        head=1;tail=0;        inde[++tail]=1;        ed=1;        ans=0;        for(i=1; i<=n; i++)        {                         while(head<=tail && inde[head]<i)head++;            while(ed<=n && sum[ed]-sum[i-1]-a[inde[head]]<=k)            {                ha+=b[ed];                ed++;                inde[++tail]=ed;                while(head<tail && a[inde[tail-1]]<a[inde[tail]]){inde[tail-1]=inde[tail];tail--;}            }            ans=ans<ha?ha:ans;            ha-=b[i];        }        printf("%d\n", ans);    }}


0 0
原创粉丝点击