One day, CYLL found an interesting piece of commercial from newspaper: the Cyber-restaurant was offering a kind of “Lunch Special” which was said that one could “buy one get two for free”. That is, if you buy one of the dishes on their menu, denoted by di
with price pi, you may get the two neighboring dishes di−1 and di+1 for free! If you pick up d1, then you may get d2and the last one dn for free, and if you choose the last one dn , you may get dn−1 and d1 for free.
However, after investigation CYLL realized that there was no free lunch at all. The price pi
of the i-th dish was actually calculated by adding up twice the cost ci
of the dish and half of the costs of the two “free” dishes. Now given all the prices on the menu, you are asked to help CYLL find the cost of each of the dishes.
Format of function:
void Price( int n, double p[] );
where int n satisfies that 2< n ≤10000; double p[] is passed into the function as an array of prices p,i and then will be returned storing the costs of the dishes.
Sample program of judge:
#include <stdio.h>
#define Max_size 10000 /* max number of dishes */
void Price( int n, double p[] );
int main()
{
int n, i;
double p[Max_size];
scanf("%d", &n);
for (i=0; i<n; i++)
scanf("%lf", &p[i]);
Price(n, p);
for (i=0; i<n; i++)
printf("%.2f ", p[i]);
printf("\n");
return 0;
}
/* Your function will be put here */
Sample Input:
12 23.64 17.39 12.77 16.62 10.67 14.85 12.68 26.90 28.30 15.59 37.99 23.18
Sample Output:
9.20 5.58 3.24 7.00 1.99 6.36 2.25 10.01 11.52 0.50 17.65 4.88
尝试的方法:
高斯法:只能过前两个点,原因是内存不允许定义double * 10001 * 10001的数组
追赶法(?):查了才知道有这个怪异的名字。主要想法就是
x
2
x_2
x2,…
x
n
−
1
x_{n-1}
xn−1都用
x
1
x_1
x1和
x
n
x_n
xn表示,然后带到最后一个方程里解。
只能过前两个点,原因是随着迭代次数增加,
x
1
x_1
x1,
x
n
x_n
xn的系数和常数项都会变的很大,超出double范围。(主要是因为这个矩阵的元素都是正的)
参数法+LU分解:
解法:
求解:
[
2
0.5
0
.
.
.
0
0
0.5
0.5
2
0.5
.
.
.
0
0
0
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
0.5
2
0.5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
0
0
0
.
.
.
0.5
2
0.5
0.5
0
0
.
.
.
0
0.5
2
]
[
x
1
x
2
x
3
.
.
.
.
.
.
.
.
.
x
n
]
=
[
p
1
p
2
p
3
.
.
.
.
.
.
.
.
.
p
n
]
\begin{bmatrix}2&0.5&0&...&0&0&0.5\\\\0.5&2&0.5&...&0&0&0\\\\...&...&...&...&...&...&...\\\\...&...&0.5&2&0.5&...&...\\\\...&...&...&...&...&...&...\\\\0&0&0&...&0.5&2&0.5\\\\0.5&0&0&...&0&0.5&2\end{bmatrix}\begin{bmatrix}x_1\\\\x_2\\\\x_3\\\\...\\\\...\\\\...\\\\x_n\end{bmatrix}=\begin{bmatrix}p_1\\\\p_2\\\\p_3\\\\...\\\\...\\\\...\\\\p_{n}\end{bmatrix}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡20.5.........00.50.52.........0000.5...0.5...00.........2.........00...0.5...0.5000.........20.50.50.........0.52⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡x1x2x3.........xn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡p1p2p3.........pn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
不妨设原矩阵为A,设左上方n-1阶矩阵为B,设
c
=
[
0.5
,
0
,
0
,
0...
,
0.5
]
T
c=[0.5,0,0,0...,0.5]^T
c=[0.5,0,0,0...,0.5]T
则有如下关系:
A
=
[
B
c
c
T
2
]
A=\begin{bmatrix}B&c\\c^T&2\end{bmatrix}
A=[BcTc2]
代入方程可得
[
B
[
x
1
x
2
.
.
.
x
n
−
1
]
+
c
x
n
c
T
[
x
1
x
2
.
.
.
x
n
−
1
]
+
2
x
n
]
=
[
[
p
1
p
2
.
.
.
p
n
−
1
]
p
n
]
\begin{bmatrix}B\begin{bmatrix}x_1\\x_2\\...\\x_{n-1}\end{bmatrix}+cx_{n}\\\\c^T\begin{bmatrix}x_1\\x_2\\...\\x_{n-1}\end{bmatrix}+2x_n\end{bmatrix}=\begin{bmatrix}\begin{bmatrix}p_1\\\\p_2\\\\...\\\\p_{n-1}\end{bmatrix}\\\\p_n\end{bmatrix}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡B⎣⎢⎢⎡x1x2...xn−1⎦⎥⎥⎤+cxncT⎣⎢⎢⎡x1x2...xn−1⎦⎥⎥⎤+2xn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡p1p2...pn−1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤pn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
取上方方块阵建立等式
不妨设
x
i
=
u
i
x
n
+
v
i
,
i
=
1
,
2
,
.
.
.
,
n
x_i=u_ix_n+v_i,i=1,2,...,n
xi=uixn+vi,i=1,2,...,n代入等式
B
(
u
x
n
+
v
)
+
c
x
n
=
P
B(ux_n+v)+cx_n=P
B(uxn+v)+cxn=P
B
v
=
P
Bv=P
Bv=P
B
u
+
c
=
0
Bu+c=0
Bu+c=0
就把原方程求解转化为解两个n-1阶三对角矩阵
[
2
0.5
0
.
.
.
0
0
0
0.5
2
0.5
.
.
.
0
0
0
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
0.5
2
0.5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
0
0
0
.
.
.
0.5
2
0.5
0
0
0
.
.
.
0
0.5
2
]
[
u
1
u
2
u
3
.
.
.
.
.
.
.
.
.
u
n
−
1
]
=
[
−
0.5
0
.
.
.
0
.
.
.
0
−
0.5
]
\begin{bmatrix}2&0.5&0&...&0&0&0\\\\0.5&2&0.5&...&0&0&0\\\\...&...&...&...&...&...&...\\\\...&...&0.5&2&0.5&...&...\\\\...&...&...&...&...&...&...\\\\0&0&0&...&0.5&2&0.5\\\\0&0&0&...&0&0.5&2\end{bmatrix}\begin{bmatrix}u_1\\\\u_2\\\\u_3\\\\...\\\\...\\\\...\\\\u_{n-1}\end{bmatrix}=\begin{bmatrix}-0.5\\\\0\\\\...\\\\0\\\\...\\\\0\\\\-0.5\end{bmatrix}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡20.5.........000.52.........0000.5...0.5...00.........2.........00...0.5...0.5000.........20.500.........0.52⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡u1u2u3.........un−1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡−0.50...0...0−0.5⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
[
2
0.5
0
.
.
.
0
0
0
0.5
2
0.5
.
.
.
0
0
0
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
0.5
2
0.5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
0
0
0
.
.
.
0.5
2
0.5
0
0
0
.
.
.
0
0.5
2
]
[
v
1
v
2
v
3
.
.
.
.
.
.
.
.
.
v
n
−
1
]
=
[
p
1
p
2
p
3
.
.
.
.
.
.
.
.
.
p
n
−
1
]
\begin{bmatrix}2&0.5&0&...&0&0&0\\\\0.5&2&0.5&...&0&0&0\\\\...&...&...&...&...&...&...\\\\...&...&0.5&2&0.5&...&...\\\\...&...&...&...&...&...&...\\\\0&0&0&...&0.5&2&0.5\\\\0&0&0&...&0&0.5&2\end{bmatrix}\begin{bmatrix}v_1\\\\v_2\\\\v_3\\\\...\\\\...\\\\...\\\\v_{n-1}\end{bmatrix}=\begin{bmatrix}p_1\\\\p_2\\\\p_3\\\\...\\\\...\\\\...\\\\p_{n-1}\end{bmatrix}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡20.5.........000.52.........0000.5...0.5...00.........2.........00...0.5...0.5000.........20.500.........0.52⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡v1v2v3.........vn−1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡p1p2p3.........pn−1⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤
最后利用
x
n
=
p
n
−
0.5
v
1
−
0.5
v
n
−
1
0.5
u
1
+
0.5
u
n
−
1
x_n=\frac{p_n-0.5v_1-0.5v_{n-1}}{0.5u_1+0.5u_{n-1}}
xn=0.5u1+0.5un−1pn−0.5v1−0.5vn−1解出
x
n
x_{n}
xn然后迭代求解。
解三对角矩阵:
用Court分解法
上代码
void CF(double* p, int n,double* x){
double z[10001];
double u[10001];
z[0]=p[0]/2;
u[0]=0.25;
double l;
for(int i=1;i<n-1;i++){
l=2-0.5*u[i-1];
u[i]=0.5/l;
z[i]=(p[i]-0.5*z[i-1])/l;
}
l=2-0.5*u[n-2];
z[n-1]=(p[n-1]-0.5*z[n-2])/l;
x[n-1]=z[n-1];
for(int i=n-2;i>=0;i--){
x[i]=z[i]-u[i]*x[i+1];
}
}
void Price( int n, double p[] ){
double p1[10001];
p1[0]=p1[n-2]=-0.5;
for(int i=1;i<n-2;i++) p1[i]=0;
double u[10001],v[10001];
CF(p1,n-1,u);
CF(p,n-1,v);
double x[10001];
x[n-1]=(p[n-1]-0.5*v[0]-0.5*v[n-2])/(2+0.5*u[0]+0.5*u[n-2]);
for(int i=0;i<n-1;i++){
x[i]=u[i]*x[n-1]+v[i];
}
for(int i=0;i<n;i++){
p[i]=x[i];
}
}
参考:
https://wenku.baidu.com/view/262c84ac941ea76e59fa042c.html#
https://blog.csdn.net/qq_32096491/article/details/78213914
祝大家解题愉快!