做法:
- 很好的一个思维题
- 题意向我们保证当前的浪花的痕迹不会完全覆盖之前的浪花的痕迹,所以我们要逆向思维,倒着来,从最后的浪花的痕迹往前思考。如果能找到第一个比当前浪花痕迹短的,那么保留的痕迹就是当前的痕迹-第一个比当前短的浪花的痕迹
- 否则,它的痕迹如果是最小的,那么直接加入答案。
- 这个题用STL写的话,利用一个set,然后二分查,就非常容易理解。
AC代码:
#include<bits/stdc++.h>
#define IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x) push_back(x)
#define sz(x) (int)(x).size()
#define sc(x) scanf("%d",&x)
#define pr(x) printf("%d\n",x)
#define abs(x) ((x)<0 ? -(x) : x)
#define all(x) x.begin(),x.end()
#define mk(x,y) make_pair(x,y)
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 1e8+5;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
set<int> s;
ll solve(vector<int> e)
{
s.clear();
int n = e.size();
ll ans = 0;
for(int i=n-1;i>=0;i--)
{
auto it = s.lower_bound(e[i]);
if(it == s.begin()) ans+=e[i];//如果当前值是最小的那么直接加
else{
it--; //找第一个比当前值小的
ans += e[i]-*it;
}
s.insert(e[i]);
}
return ans;
}
int main()
{
#ifdef LOCAL_FILE
freopen("in.txt","r",stdin);
#endif // LOCAL_FILE
vector<int> x,y;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
ll xx,yy;
cin>>xx>>yy;
x.pb(xx);
y.pb(yy);
}
cout<<solve(x)+solve(y)<<endl;
return 0;
}