KSzsh

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

Remove the Bracket

题目链接

题目描述:

RSJ has a sequence a of n integers a1,a2,,an and an integer s. For each of a2,a3,,an1, he chose a pair of non-negative integers xi and yi such that xi+yi=ai and (xis)(yis)0.

Now he is interested in the value

F=a1x2+y2x3+y3x4++yn2xn1+yn1an.

Please help him find the minimum possible value F he can get by choosing xi and yi 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(1t104) — the number of test cases.

The first line of each test case contains two integers n,s(3n2105;0s2105).

The second line contains n integers a1,a2,,an(0ai2105).

It is guaranteed that the sum of n does not exceed 2105.

输出描述:

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, 20+01+03+04=0.

In the second test case, 51+22+22+15=18.

AC代码:

题目中公式

F=a1x2+y2x3+y3x4+yn2xn1+yn1an

对于i(2in1) 提取出

yi1xi+yixi+1

由于xi+yi=ai, 所以yi=aixi,带入原式中得

yi1xi+(aixi)xi+1

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

  • ais时,可以取最值0ai
  • ai>s时,可以取最值sais

这两种情况都保证满足(xis)(yis)0

这样可以采取DP

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

  • j=0时,xi取最小值时的结果
  • j=1时,xi取最大值时的结果

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

  • f[i][0]=min(f[i1][0]+maxv(yi1)minv(xi),f[i1][1]+minvminv)
  • f[i][1]=min(f[i1][0]+maxv(yi1)maxv(xi),f[i1][1]+minvmaxv)

最后结果取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   KSzh  阅读(19)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示