F. Triangular Paths
题意:
初始给定一个数字三角形,无限大的
大概长这样,一个节点有两种边,初始向下或者向右下,花费
1
1
1 可以更改为另一条
给定
n
n
n 个点,坐标
(
r
,
c
)
(r,c)
(r,c) 表示第
r
r
r 行第
c
c
c 列
求从
(
1
,
1
)
(1,1)
(1,1) 开始走,走完这
n
n
n 个点的最小花费
思路:
这些边都是向下指的,每次必然下降一层,因此访问这
n
n
n 个节点的顺序是一定的,就是按照他们的层数访问,所以最小代价即为相邻节点的路径的代价和
然后分类讨论,找规律计算贡献
具体看代码应该能理解
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 2e5 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int f(int r1, int c1, int r2, int c2)
{
if((r1 + c1) % 2 == 0)
{
if(r1 - c1 == r2 - c2) return r2 - r1;
return ((r2 - c2) - (r1 - c1)) / 2;
}
return ((r2 - c2) - (r1 - c1) + 1) / 2;
}
void work()
{
cin >> n;
vector <pair<int,int> > v(n + 1);
v[0] = {1, 1};
for(int i = 1; i <= n; ++i) cin >> v[i].first;
for(int i = 1; i <= n; ++i) cin >> v[i].second;
sort(all(v));
ll ans = 0;
for(int i = 1; i < v.size(); ++i){
int r1 = v[i-1].first, c1 = v[i-1].second;
int r2 = v[i].first, c2 = v[i].second;
ans += f(r1, c1, r2, c2);
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(0);
int TT;cin>>TT;while(TT--)
work();
return 0;
}