KSzsh

导航

Remove the Bracket

题目链接

题目描述:

RSJ has a sequence \(a\) of \(n\) integers \(a_1,a_2,…,a_n\) and \(a_n\) integer \(s\). For each of \(a_2,a_3,…,a_{n−1}\), he chose a pair of non-negative integers \(x_i\) and \(y_i\) such that \(x_i+y_i=a_i\) and \((x_i−s)⋅(y_i−s)≥0\).

Now he is interested in the value

\[F=a_1⋅x_2+y_2⋅x_3+y_3⋅x_4+…+y_{n−2}⋅x_{n−1}+y_{n−1}⋅a_n. \]

Please help him find the minimum possible value \(F\) he can get by choosing \(x_i\) and \(y_i\) optimally. It can be shown that there is always at least one valid way to choose them.

输入描述:

Each test contains multiple test cases. The first line contains an integer \(t(1≤t≤10^4 )\) — the number of test cases.

The first line of each test case contains two integers \(n, s (3≤n≤2⋅10^5; 0≤s≤2⋅10^5)\).

The second line contains \(n\) integers \(a_1,a_2,…,a_n(0≤a_i≤2⋅10^5)\).

It is guaranteed that the sum of \(n\) does not exceed \(2⋅10^5\).

输出描述:

For each test case, print the minimum possible value of \(F\).

样例:

input:

10
5 0
2 0 1 3 4
5 1
5 3 4 3 5
7 2
7 6 5 4 3 2 1
5 1
1 2 3 4 5
5 2
1 2 3 4 5
4 0
0 1 1 1
5 5
4 3 5 6 4
4 1
0 2 1 0
3 99999
200000 200000 200000
6 8139
7976 129785 12984 78561 173685 15480

output:

0
18
32
11
14
0
16
0
40000000000
2700826806

Note:

In the first test case, \(2⋅0+0⋅1+0⋅3+0⋅4=0\).

In the second test case, \(5⋅1+2⋅2+2⋅2+1⋅5=18\).

AC代码:

题目中公式

\[F = a_1 \cdot x_2 + y_2 \cdot x_3 + y_3 \cdot x_4 + y_{n - 2} \cdot x_{n - 1} + y_{n - 1} \cdot a_n \]

对于\(\forall\)\(i(2 ≤ i ≤ n - 1)\) 提取出

\[y_{i - 1} \cdot x_i + y_i \cdot x_{i + 1} \]

由于\(x_i + y_i = a_i\), 所以\(y_i = a_i - x_i\),带入原式中得

\[y_{i - 1} \cdot x_i + (a_i - x_i) \cdot x_{i + 1} \]

所以原式就变成了关于\(x_i\)的一次函数,那么函数的最值也就是会在\(x_i\)取最值的时候取到

  • \(a_i ≤s\)时,可以取最值\(0\)\(a_i\)
  • \(a_i >s\)时,可以取最值\(s\)\(a_i - s\)

这两种情况都保证满足\((x_i - s) \cdot (y_i - s) ≥ 0\)

这样可以采取DP

采用一个数组\(f[i][j]\),其状态表示为

  • \(j = 0\)时,\(x_i\)取最小值时的结果
  • \(j = 1\)时,\(x_i\)取最大值时的结果

\(f[i][j]\)则有可能是从\(f[i - 1][0]\)\(f[j - 1][1]\) 中转移过来,所以状态计算为

  • \(f[i][0] = min(f[i - 1][0] + maxv(y_{i - 1}) \cdot minv(x_i), f[i - 1][1] + minv \cdot minv)\)
  • \(f[i][1] = min(f[i - 1][0] + maxv(y_{i - 1}) \cdot maxv(x_i),f[i - 1][1] + minv \cdot maxv)\)

最后结果取\(f[n][0]\)\(f[n][1]\)的最小值即可(最终结果\(f[n][0]\)\(f[n][1]\)大小是一样的,但是我不明白为什么)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 2e5 + 10;

LL f[N][2];
LL x[N], y[N];

void solve()
{
	int n, s;
	cin >> n >> s;

	for(int i = 1; i <= n; i ++)
	{
		int m;
		cin >> m;

		if(i == 1 || i == n)
		{
			x[i] = y[i] = m;
		}
		else if(m <= s)
		{
			x[i] = 0, y[i] = m;
		}
		else
		{
			x[i] = min(s, m - s), y[i] = max(s, m - s);
		}
	}

	f[1][0] = f[1][1] = 0;

	for(int i = 2; i <= n; i ++)
	{
		f[i][0] = min(f[i - 1][0] + y[i - 1] * x[i], f[i - 1][1] + x[i - 1] * x[i]);
		f[i][1] = min(f[i - 1][0] + y[i - 1] * y[i], f[i - 1][1] + x[i - 1] * y[i]);
	}
	
	cout << f[n][0] << '\n';
}

int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	int T;
	cin >> T;

	while(T --)
		solve();

	return 0;
}

posted on 2023-02-01 11:00  KSzh  阅读(17)  评论(0编辑  收藏  举报