4273: 玩具
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 700 Solved: 129
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
——————————————————————————————
题目的意思是在n个物品对应不同的价格和价值,选取一段连续的区间减去区间最大值后在给出的范围内的最大价值
算出区间的最大值,RMQ处理,然后计算出每段区间的价值去最大,可以用尺取发做
#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<queue>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define inf 0x3f3f3f3f
int v[5000],w[5005];
int d[5000][30];
int n;
int m;
void init()
{
for(int i=0; i<n; i++)
d[i][0]=w[i];
for(int i=1; (1<<i)<=n; i++)
for(int j=0; j+(1<<i)-1<n; j++)
d[j][i]=max(d[j][i-1],d[j+(1<<(i-1))][i-1]);
}
int query(int L,int R)
{
int k=0;
while((1<<(k+1))<=R-L+1) k++;
return max(d[L][k],d[R-(1<<k)+1][k]);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
memset(w,0,sizeof w);
memset(v,0,sizeof v);
memset(d,0,sizeof d);
for(int i=0; i<n; i++)
scanf("%d",&w[i]);
for(int i=0; i<n; i++)
scanf("%d",&v[i]);
init();
int L=0;
int R=0;
int sum=0;
int ans=0;
int mx=-1;
while(L<n&&R<n)
{
int x=sum+w[R]-query(L,R);
if(x<=m)
{
sum+=w[R];
ans+=v[R];
mx=max(mx,ans);
R++;
}
else
{
sum-=w[L];
ans-=v[L];
L++;
}
}
printf("%d\n",mx);
}
return 0;
}