1 条题解
-
0
题意分析
给定一个长度为的整数序列,需要构造一个长度相同的序列,使得以下两部分之和最小:
- 与的绝对差之和:
- 序列相邻元素的绝对差之和:
解题思路
- 问题分解:
- 第一部分要求尽可能接近(使最小)
- 第二部分要求序列尽可能平滑(使相邻元素变化最小)
- 关键观察:
- 最优解中的取值范围应在序列的最小值和最大值之间
- 可通过动态规划求解,状态设计需考虑当前的取值对后续的影响
实现步骤
- 预处理:
- 确定序列的最小值和最大值
- 枚举的可能取值范围(到)
- 动态规划:
- 定义表示处理到第个元素时的最小值
- 状态转移方程:
$dp[i][j] = |A(i)-j| + \min_{k} (dp[i-1][k] + |k-j|)$
- 结果提取:
- 最终结果为
代码实现
#include<stdio.h> #include<string.h> #include<math.h> #define INF 0x3fffffff #include<iostream> using namespace std; int mad(int a,int b,int c) {//取三个数的中间值 int ma=a,mi=a; ma=max(a,b); ma=max(ma,c); mi=min(a,b); mi=min(mi,c); return a+b+c-mi-ma; } int main() { int a[1000]; int b[1000]; int n; int s=0; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d",&a[i]); b[i]=a[i]; } for(int i=1; i<n-1; i++) { b[i]=mad(b[i-1],a[i],b[i+1]); } for(int i=0; i<n; i++) { s+=fabs(a[i]-b[i]); } for(int i=1; i<n; i++) s+=fabs(b[i]-b[i-1]); printf("%d\n",s); return 0; }
- 1
信息
- ID
- 1314
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者