列表

详情


NC50036. 干物妹小埋

描述

在之前很火的一个动漫《干物妹小埋》中,大家对小埋打游戏喝可乐的印象十分的深刻。
现在欧尼酱将小埋的快乐水全部分开藏在了家具的顶端。
小埋使出空中1080°转身接战术翻滚跳到任一家具上,她相信,只要她翻滚的足够快,欧尼酱就跟不上她。
 
1.为获取梦幻开局,小埋一套技能可以使她一开始掉落在任一家具上。
2.埋家的家具按顺序给出,每个家具可跳可不跳,为避开欧尼酱的追击,小埋翻滚到某个家具上面后,只能向前继续翻滚。
3.启动超重力感应系统的小埋不会从较高的家具翻滚到较低的家具上。
4.由于每个家具上的快乐水都有对应的happy值,IQ==250的小埋会选择一条happy值总和最大的路线。
那么,最终小埋将获得的happy值总和是多少呢?

输入描述

第一行一个整数n(0<n<=200000),表示小埋家的家具数。

第二行n个整数,对于每个整数ai, 0<=ai<=10^9,表示第i个家具的高度。

第三行n个整数,对于每个整数vi, 0<=vi<=10^9,表示第i个家具上的快乐水的happy值。

输出描述

一个整数,表示小埋获得的happy值总和。

示例1

输入:

6
2 1 1 3 3 4
3 1 1 1 1 1

输出:

6

说明:

路线:2->3->3->4

答案:3+1+1+1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 237ms, 内存消耗: 5348K, 提交时间: 2019-07-14 16:38:50

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define maxN 200005
LL n, L, v[maxN], a[maxN], T[maxN];
LL c[maxN];

void update(int i, LL x) {
  for (; i <= L; i += i & -i)
    T[i] = max(T[i], x);
}
LL query(int i) {
  LL ans = 0;
  for (; i; i -= i & -i)
    ans = max(ans, T[i]);
  return ans;
}
int main () {
  scanf("%d", &n);
  FOR(i, 0, n - 1) cin>>v[i],a[i] = v[i];
  FOR(i, 0, n - 1) cin>>c[i];
  sort(a, a + n);
  L = unique(a, a + n) - a;
  LL ans = 0, t;
  FOR(i, 0, n - 1) {
    int p = lower_bound(a, a + L, v[i]) - a + 1;
    t = query(p) + c[i];
    ans = max(ans, t);
    update(p, t);
  }
  cout<<ans<<endl;
  return 0;
}

C++14(g++5.4) 解法, 执行用时: 247ms, 内存消耗: 5476K, 提交时间: 2019-07-19 15:10:16

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;

int n;
ll c[N],a[N],b[N],ans;
vector<ll>v;
 
int lb(int x){return x&(-x);}
void update(int x,ll k){
	while(x<N){
		c[x]=max(c[x],k);
		x+=lb(x);
	}
}
ll get_max(int x)
{
	ll res=0;
	while(x){
		res=max(res,c[x]);
		x-=lb(x);
	}return res;
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		v.push_back(a[i]);
	}
	sort(v.begin(),v.end());
	v.erase(unique(v.begin(),v.end()),v.end());
	for(int i=1;i<=n;i++){
		cin>>b[i];
		int x=lower_bound(v.begin(),v.end(),a[i])-v.begin()+1;
		ll tmp=get_max(x);
		ans=max(ans,b[i]+tmp);
		update(x,b[i]+tmp);	
	}
	cout<<ans<<endl;
	return 0;
}

上一题