P9325 的题解捏
思路
看到题目,首先第一眼想到暴力。
最朴素的暴力方法肯定是先枚举长度
暴力代码:
#include <iostream>
using namespace std;
typedef long long ll;
#define int long long
int a[10101];
signed main(){
int n;
scanf("%lld", &n);
for(int i = 1; i <= n; ++i){
scanf("%lld", &a[i]);
}
for(int len = 1; len <= n; ++len){
int l = 1, r = len;
int cz = 1e15;
while(r <= n){
int L = l, R = r, nowcz = 0;
while(L <= R){
nowcz += abs(a[L] - a[R]);
L++;
R--;
}
++l;++r;
cz = min(cz, nowcz);
}
printf("%lld ", cz);
}
return 0;
}
接下来就是本篇的重点:优化(当然我也不会和你说什么 dp 和双指针之类的)。
我们不妨举个例子:
初始时假设
由于奇偶性不同,
复杂度是
#include <iostream>
using namespace std;
typedef long long ll;
ll h[10101];
ll a[10101], b[10101];
int main(){
int n;
scanf("%lld", &n);
for(int i = 1; i <= n; ++i) scanf("%lld", &h[i]);
printf("0 ");
for(int i = 2; i <= n; ++i){
if(i % 2 == 1){
int l = n-i+1, r = n;
ll cz = 1e15;
while(r >= i){
a[r] = a[r-1] + abs(h[r] - h[l]);
cz = min(cz, a[r]);
--l;--r;
}
printf("%lld ", cz);
}else{
int l = n-i+1, r = n;
ll cz = 1e15;
while(r >= i){
b[r] = b[r-1] + abs(h[r] - h[l]);
cz = min(cz, b[r]);
--l;--r;
}
printf("%lld ", cz);
}
}
return 0;
}