门前大桥下,游过一群鱼,小红鱼,黄花鱼,绿草鱼,蓝顶鱼,粉鲳鱼,砂紫鱼,竟然在鱼塘中排成了一条队列,捕鱼达人坤坤打算将他们捕获。但是由于这些鱼比较稀有,坤坤需要在指定的规则下才能抓捕他们,规则如下:
-
在捕鱼过程中当前捕获的鱼颜值必须大于等于前一条鱼颜值a_i,对于捕获的第一条鱼没有要求。
-
每一条鱼变身后他的价值b_i为他的颜值的1/10000(整除)。
-
每一条鱼变身后他的颜值会变成原本颜值对10000的余数,也就是a_i%10000。(例如变身前颜值a_i为20001,则变身后它的价值变为2,颜值变为1)。
-
所有鱼在一开始的时候就会变身,变身后坤坤才可以开始捕鱼。
-
鱼群顺序是从左到右排列的,鱼群的顺序是不可变的,坤坤可以从鱼群头或者鱼群尾开始捕鱼,但是顺序必须是从左到右或者从右到左。
-
坤坤希望他捕获到的鱼的价值最多。
输入要求
第一行先输入一个T(1 <= T <= 10)表示接下去有T组数据
对于每组数据
第一行会有一个n(1 <= n <= 10^4)表示接下来从左到右会有n条鱼。
第二行会有n个数,对于每个数表示这个鱼的颜值为a_i(-6 * 10^4 < a_i < 6 * 10^4)。
输出要求
对于每组数据,输出Case #i: val
表示当前为第i组数据,每次捕鱼获得的最大价值为val。
对于每行输出,最后没有空格,输出后直接换行。
样例输入
5
5
10001 10002 10003 10004 10001
5
50001 10001 10002 10003 10004
5
50001 10002 10003 10004 10005
5
50005 10001 10002 10003 10004
5
-10001 -10002 -10003 -10004 0
样例输出
Case #1: 4
Case #2: 9
Case #3: 9
Case #4: 6
Case #5: 0
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 10010;
const int maxm = 20010;
int dp[maxm],n;
int a[maxn];//颜值
int b[maxn];
int h[maxm];
int lowbit(int x) {
return x&(-x);
}
void update(int x) {//单点更新
while(x < maxm) {
h[x] = dp[x];
for(int i = 1;i < lowbit(x);i <<= 1)
h[x] = max(h[x],h[x-i]);
x += lowbit(x);
}
return;
}
int query(int st,int ed) {//查询区间最大值
int ans = 0;
while(ed >= st) {
ans = max(ans,dp[ed]);
--ed;
for(;ed-lowbit(ed) >= st;ed -= lowbit(ed)) {
ans = max(ans,h[ed]);
}
}
return ans;
}
int main() {
int t,cas = 1;scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i = 1,x;i <= n;++i) {
scanf("%d",&x);
a[i] = x%10000+10000;
b[i] = x/10000;
}
for(int i = 0;i < maxm;++i) dp[i] = h[i] = 0;
int ans = 0;
for(int i = 1;i <= n;++i) {
int val = a[i];
// for(int j = 0;j < a[i];++j) {
// dp[val] = max(dp[val],dp[j]);
// }
if(a[i] > 0)
dp[val] = query(1,a[i]);
if(b[i] > 0) {
dp[val] += b[i];
update(val);
}
ans = max(ans,dp[val]);
}
for(int i = 0;i < maxm;++i) dp[i] = h[i] = 0;
for(int i = n;i >= 1;--i) {
int val = a[i];
// for(int j = 0;j < a[i];++j) {
// dp[val] = max(dp[val],dp[j]);
// }
if(a[i] > 0)
dp[val] = query(1,a[i]);
if(b[i] > 0) {
dp[val] += b[i];
update(val);
}
ans = max(ans,dp[val]);
}
printf("Case #%d: %d\n",cas++,ans);
}
}