题意:
给出一个有
n
n
n个元素的数组
a
a
a和一个常数
s
s
s,将每个元素
a
i
a_{i}
ai分解为两个数
x
i
,
y
i
x_{i},y_{i}
xi,yi,满足
x
i
+
y
i
=
a
i
x
i
≥
0
y
i
≥
0
(
x
i
−
s
)
⋅
(
y
i
−
s
)
≥
0
x_{i}+y_{i}=a_{i}\\ x_{i}\geq 0 \\ y_{i}\geq 0 \\ (x_{i}-s)\cdot(y_{i}-s)\geq 0
xi+yi=aixi≥0yi≥0(xi−s)⋅(yi−s)≥0
记
F
F
F为
F
=
a
1
x
2
+
y
2
x
3
+
y
3
x
4
+
.
.
.
.
+
y
n
−
2
x
n
−
1
+
y
n
−
1
a
n
F=a_{1}x_{2}+y_{2}x_{3}+y_{3}x_{4}+....+y_{n-2}x_{n-1}+y_{n-1}a_{n}
F=a1x2+y2x3+y3x4+....+yn−2xn−1+yn−1an
求出
F
F
F的最小值
Solution:
如果按顺序地考虑
a
i
a_{i}
ai的分解情况,对
i
∈
[
3
,
n
−
1
]
i\in[3,n-1]
i∈[3,n−1]的分解情况只会影响到
y
i
−
1
x
i
+
y
i
x
i
+
1
y_{i-1}x_{i}+y_{i}x_{i+1}
yi−1xi+yixi+1这两项,同时有
y
i
=
a
i
−
x
i
y_{i}=a_{i}-x_{i}
yi=ai−xi
则影响到的项为
y
i
−
1
x
i
+
(
a
i
−
x
i
)
x
i
+
1
y_{i-1}x_{i}+(a_{i}-x_{i})x_{i+1}
yi−1xi+(ai−xi)xi+1
除了下标为
i
i
i的项都是常数,那么这就是一个关于
x
i
x_{i}
xi的一次函数,只会在
x
i
x_{i}
xi的可能取值范围端点处取得最值
按题意,
x
i
x_{i}
xi的取值范围为下列两个不等式组的并集
{
x
i
≤
s
y
i
=
a
i
−
x
i
≤
s
x
i
≥
0
y
i
=
a
i
−
x
i
≥
0
\begin{cases} x_{i}\leq s \\ y_{i}=a_{i}-x_{i}\leq s \\ x_{i}\geq 0 \\ y_{i}=a_{i}-x_{i} \geq 0 \end{cases}
⎩
⎨
⎧xi≤syi=ai−xi≤sxi≥0yi=ai−xi≥0
{ x i ≥ s y i = a i − x i ≥ s x i ≥ 0 y i = a i − x i ≥ 0 \begin{cases} x_{i}\geq s \\ y_{i}=a_{i}-x_{i}\geq s \\ x_{i}\geq 0 \\ y_{i}=a_{i}-x_{i} \geq 0 \end{cases} ⎩ ⎨ ⎧xi≥syi=ai−xi≥sxi≥0yi=ai−xi≥0
这两个不等式组的解集为
[
m
a
x
(
0
,
m
i
n
(
s
,
a
[
i
]
−
s
)
)
,
m
i
n
(
a
[
i
]
,
m
a
x
(
s
,
a
[
i
]
−
s
)
)
]
[max(0,min(s,a[i]-s)),min(a[i],max(s,a[i]-s))]
[max(0,min(s,a[i]−s)),min(a[i],max(s,a[i]−s))]
接下来只需要
d
p
dp
dp取最大最小值的情况即可,设
d
p
[
i
]
[
0
/
1
]
dp[i][0/1]
dp[i][0/1]为将
a
i
a_{i}
ai分解为
x
i
x_{i}
xi最小或最大的情况下前
i
i
i项的最小取值
当
i
=
2
i=2
i=2时
d
p
[
2
]
[
0
]
=
a
[
1
]
⋅
x
[
2
]
[
0
]
d
p
[
2
]
[
1
]
=
a
[
1
]
⋅
x
[
2
]
[
1
]
dp[2][0]=a[1]\cdot x[2][0]\\ dp[2][1]=a[1]\cdot x[2][1]\\
dp[2][0]=a[1]⋅x[2][0]dp[2][1]=a[1]⋅x[2][1]
当
3
≤
i
≤
n
−
1
3\leq i \leq n-1
3≤i≤n−1时,枚举当前计算的状态
j
j
j,和从
i
−
1
i-1
i−1转移来的状态
k
k
k,有
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
]
[
j
]
,
d
p
[
i
−
1
]
[
k
]
+
y
[
i
−
1
]
[
k
]
⋅
x
[
i
]
[
j
]
)
dp[i][j]=min(dp[i][j],dp[i-1][k]+y[i-1][k]\cdot x[i][j]) \\
dp[i][j]=min(dp[i][j],dp[i−1][k]+y[i−1][k]⋅x[i][j])
F
F
F与
a
n
a_{n}
an的分配无关,答案就为
m
i
n
(
d
p
[
n
−
1
]
[
0
]
+
y
[
n
−
1
]
[
0
]
⋅
a
[
n
]
,
d
p
[
n
−
1
]
[
1
]
+
y
[
n
−
1
]
[
1
]
⋅
a
[
n
]
)
min(dp[n-1][0]+y[n-1][0]\cdot a[n],dp[n-1][1]+y[n-1][1]\cdot a[n])
min(dp[n−1][0]+y[n−1][0]⋅a[n],dp[n−1][1]+y[n−1][1]⋅a[n])
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<bitset>
#include<cstdlib>
#include<cassert>
#include<cstring>
#include<cmath>
#include<utility>
#include<vector>
#include<cctype>
#include<utility>
#include<stack>
#include<queue>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<ctime>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
using ll=long long;
const int N=2e5+5,inf=0x3fffffff;
const ll INF=0x3fffffffffffffff,mod=1e9+7;
ll dp[N][2],x[N][2],y[N][2],last[N][2];
int n,s,a[N];
inline void work() {
cin>>n>>s;
/**
* x[i]+y[i]=a[i]
* (x[i]-s)*(y[i]-s)>=0
* F=a[1]*x[2]+(y[2]*x[3]+y[3]*x[4]+...+y[n-2]*x[n-1])+y[n-1]*a[n];
*/
for(int i=1;i<=n;i++) {
cin>>a[i];
x[i][0]=max(0,min(s,a[i]-s));
x[i][1]=min(a[i],max(s,a[i]-s));
for(int j=0;j<=1;j++) {
y[i][j]=a[i]-x[i][j];
dp[i][j]=INF;
}
}
dp[2][0]=a[1]*x[2][0];
dp[2][1]=a[1]*x[2][1];
for(int i=3;i<n;i++) {
for(int j=0;j<=1;j++) {
for(int k=0;k<=1;k++) {
dp[i][j]=min(dp[i][j],dp[i-1][k]+y[i-1][k]*x[i][j]);
}
}
}
cout<<min(dp[n-1][0]+y[n-1][0]*a[n],dp[n-1][1]+y[n-1][1]*a[n])<<endl;
}
int main() {
#ifdef stdjudge
freopen("in.txt","r",stdin);
#endif
cin.tie(nullptr);
ios::sync_with_stdio(false);
int t; cin>>t;
while(t--) work();
#ifdef stdjudge
freopen("CON","r",stdin);
std::cout<<std::flush;
system("pause");
#endif
return 0;
}