4273: 玩具
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 861 Solved: 181
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
Source
解题思路:枚举起点,二分终点,rmq保存区间最大值
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <climits>
using namespace std;
#define LL long long
const int INF=0x3f3f3f3f;
LL sum1[5005],a[5005],b[5005],k,dp[5005][15],sum2[5005];
int n;
void RMQ()
{
for(int i=1;i<=n;i++) dp[i][0]=a[i];
for(int i=1;(1<<i)<=n;i++)
{
for(int j=1;j+(1<<i)-1<=n;j++)
dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
}
}
LL query(int x,int y)
{
int k=0;
while(1<<(k+1)<=y-x+1) k++;
return max(dp[x][k],dp[y-(1<<k)+1][k]);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%lld",&n,&k);
sum1[0]=0,sum2[0]=0;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),sum1[i]=sum1[i-1]+a[i];
for(int i=1;i<=n;i++) scanf("%lld",&b[i]),sum2[i]=sum2[i-1]+b[i];
RMQ();
LL ma=0;
for(int i=1;i<=n;i++)
{
int l=i,r=n,kk;
while(l<=r)
{
int mid=(l+r)>>1;
if(sum1[mid]-sum1[i-1]-query(i,mid)<=k) kk=mid,l=mid+1;
else r=mid-1;
}
ma=max(ma,sum2[kk]-sum2[i-1]);
}
printf("%lld\n",ma);
}
return 0;
}