时间限制:2秒
空间限制:131072K
小Q和牛博士合唱一首歌曲,这首歌曲由n个音调组成,每个音调由一个正整数表示。
对于每个音调要么由小Q演唱要么由牛博士演唱,对于一系列音调演唱的难度等于所有相邻音调变化幅度之和, 例如一个音调序列是8, 8, 13, 12, 那么它的难度等于|8 - 8| + |13 - 8| + |12 - 13| = 6(其中||表示绝对值)。
现在要对把这n个音调分配给小Q或牛博士,让他们演唱的难度之和最小,请你算算最小的难度和是多少。
如样例所示: 小Q选择演唱{5, 6}难度为1, 牛博士选择演唱{1, 2, 1}难度为2,难度之和为3,这一个是最小难度和的方案了。
对于每个音调要么由小Q演唱要么由牛博士演唱,对于一系列音调演唱的难度等于所有相邻音调变化幅度之和, 例如一个音调序列是8, 8, 13, 12, 那么它的难度等于|8 - 8| + |13 - 8| + |12 - 13| = 6(其中||表示绝对值)。
现在要对把这n个音调分配给小Q或牛博士,让他们演唱的难度之和最小,请你算算最小的难度和是多少。
如样例所示: 小Q选择演唱{5, 6}难度为1, 牛博士选择演唱{1, 2, 1}难度为2,难度之和为3,这一个是最小难度和的方案了。
输入描述:
输入包括两行,第一行一个正整数n(1 ≤ n ≤ 2000) 第二行n个整数v[i](1 ≤ v[i] ≤ 10^6), 表示每个音调。
输出描述:
输出一个整数,表示小Q和牛博士演唱最小的难度和是多少。
输入例子1:
5 1 5 6 2 1
输出例子1:
3
#include <iostream> #include <string> #include <cstdio> #include <utility> #include <thread> #include <fstream> #include <chrono> #include <iterator> #include <functional> #include <vector> #include <sstream> #include <algorithm> #include <atomic> #include <deque> #include <stack> using namespace std; typedef long long LL; const int MAXN = 2009; #define INF 0x3f3f3f3f /* dp[i][j] 表示 第一组取到的最后一个人是a[i] 第二组取到的最后一个人是a[j] 由一组取完所有显然不是最优解 下一个位置max(i,j)+1 取之前有两种转移情况 反推(正推的话初始情况不好处理) */ int n; int dp[MAXN][MAXN]; int val[MAXN]; int main() { ios::sync_with_stdio(0); cin >> n; for (int i = 1; i <= n; i++) cin >> val[i]; for (int i = n; i >= 1; i--) { for (int j = n; j >= 1; j--) { int p = max(i, j) + 1; dp[i][j] = INF; dp[i][j] = min(dp[i][j], dp[i][p] + (j == 1 ? 0 : abs(val[p - 1] - val[j - 1]))); dp[i][j] = min(dp[i][j], dp[p][j] + (i == 1 ? 0 : abs(val[p - 1] - val[i - 1]))); } } cout << dp[1][1] << endl; }