[R17D]数字跳跃

dp[i][0] 达到第i个数字能达到的最小结果
dp[i][1] 达到第i个数字能达到的最大结果
如果 不选择当前数字 那么结果不变dp[i][0] = dp[i-1][0] dp[i][1] =dp[i-1][1]
如果 选择当前数字 根据公式计算最大最小 注意正负号的变动
dp[i][0]= 2a[i] - dp[i-1][1]; dp[i-1][1]最大值肯定大于等于dp[i-1][0]的最小值; 所以计算dp[i][0]的最小值的时候肯定是减去dp[i-1][1]的最大值 才可能得到最小值。
同理 dp[i][1]= 2
a[i] - dp[i-1][0];

// [R17D]数字跳跃.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
题目地址:
https://bs.daimayuan.top/p/100
题目名称:
[R17D]数字跳跃
题目描述:
定义跳跃操作:对数字 x 进行参数为 y 的跳跃操作,会将 x 变为 2×y−x。比如:对 3 进行参数为 1 的跳跃操作会变为 −1,对 3 进行参数为 4 的跳跃操作会变为 5,
对 3 进行参数为 3 的跳跃操作会变为 3。
有 n 个跳跃操作,编号为 1∼n,编号 i 的跳跃操作参数为 a_i。
初始数字 x=0,你选择一些(可以选 0 个)跳跃操作,并按编号从小到大的顺序对 x 依次进行这些跳跃操作,求最终 x 最大是多少。
输入格式:
第一行包含一个整数 n,表示跳跃操作的数量。
第二行包含 n 个整数 a_i,分别表示每个跳跃操作的参数。
输出格式:
输出一个整数,表示最终 x 的最大值。
数据范围:
对于 30% 的数据,n≤20。
另有 30% 的数据,n≤1000,−10≤a_i≤10。
对于 100% 的数据,1≤n≤10^5,−10^9≤a_i≤10^9。
样例输入:
5
5 4 3 1 2
样例输出:
12
样例解释:
其中一种方案为依次进行编号为 1,4,5 的跳跃操作,x 的变化过程为:0⇒10⇒−8⇒12。
样例输入:
1
-2
样例输出:
0
样例输入:
11
1000000000 -1000000000 1000000000 -1000000000 1000000000 -1000000000 1000000000 -1000000000 1000000000 -1000000000 1000000000
样例输出:
22000000000

*/
#include <iostream>
#include <cstring>


using namespace std;

const int N = 100010;
int a[N];
long long dp[N][2];
int n;


int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	memset(dp, -1, sizeof(dp));
	dp[0][0] = 0; dp[0][1] = 0;
	for (int i = 1; i <= n; i++) {
		dp[i][0] = min(dp[i - 1][0], 2 * a[i] - dp[i - 1][1]);
		dp[i][1] = max(dp[i - 1][1],2*a[i]-dp[i-1][0]);
	}

	cout << max(dp[n][0], dp[n][1]) << endl;


	return 0;
}

posted on 2025-07-14 14:41  itdef  阅读(78)  评论(0)    收藏  举报

导航