給定乙個長為n的整數序列,由a和b輪流取數(a先取)。每個人可從序列的左端或右端取若干個數(至少乙個),但不能兩端都取。所有數都被取走後,兩人分別統計所取數的和作為各自的得分。假設a和b都足夠聰明,都使自己得分盡量高,求a的最終得分。
時限3s3s
,顯然是要乙個常數小的o(t
n2)o
(tn2
)的方法。
由於每次a和b都只可以在左右兩端取數,所以取完後剩餘的一定是乙個連續的子區間。
正序做似乎不是很好做,考慮倒序,將問題轉化成乙個區間問題。
先考慮最暴力的方法,若先手取時剩餘區間為[l,
r][l
,r],那麼後手一定是取了[x,
r][x
,r]或[
l,x]
(l<
x[l,x
](l<
x,然後先手取[l,
x−1]
[l,x
−1]或[
x+1,
r][x
+1,r
]。設dp
[i][
j]dp
[i][
j]表示先手取成[l,
r][l
,r]的最優答案,那麼這個答案一定由後手的最劣方案轉移而來。因為若後手取後的區間和為s′s
′,區間[l,
r][l
,r]的和為s
s,那麼先手取的和為s−s
′s−s
′。我們要讓s−s
′s−s
′盡量大,那麼就讓s′s
′盡量小即可。即後手的最劣方案。
所以轉移方程就是dp
[i][
j]=s
um[j
]−su
m[i−
1]−m
in(0
,dp[
i][i
],dp
[i][
i+1]
,...
,dp[
i][j
−1],
dp[j
][j]
,dp[
j−1]
[j],
...,
dp[i
+1][
j])d
p[i]
[j]=
sum[
j]−s
um[i
−1]−
min(
0,dp
[i][
i],d
p[i]
[i+1
],..
.,dp
[i][
j−1]
,dp[
j][j
],dp
[j−1
][j]
,...
,dp[
i+1]
[j])
其中sum[
i]su
m[i]
為a[i]
a[i]
的字首和,sum
[j]−
sum[
i−1]
sum[
j]−s
um[i
−1]即∑
k=ij
a[k]
∑k=i
ja[
k];加上0的原因是因為先手可以一次把所有選完,那麼後手就不能選,即選的和為0。
這樣單次詢問的複雜度是o(n
3)o(
n3)的。
看到方程中有min
min,m
inmi
n需要o(n
)o(n
)的複雜度,但是dpd
p中的min
min一般都是可以進行轉移的。所以可以通過轉移min
min來去掉這個o(n
)o(n
)。設f[
i][j
]=mi
n(dp
[i][
i],d
p[i]
[i+1
],..
.,dp
[i][
j]),
g[i]
[j]=
min(
dp[j
][j]
,dp[
j−1]
[j],
...d
p[i]
[j])
f[i]
[j]=
min(
dp[i
][i]
,dp[
i][i
+1],
...,
dp[i
][j]
),g[
i][j
]=mi
n(dp
[j][
j],d
p[j−
1][j
],..
.dp[
i][j
])。方程就變成了dp
[i][
j]=s
um[j
]−su
m[i−
1]−m
in(0
,f[i
+1][
j],g
[i][
j−1]
)dp[
i][j
]=su
m[j]
−sum
[i−1
]−mi
n(0,
f[i+
1][j
],g[
i][j
−1])
f,gf
,g的維護都是最最最最基礎的了。顯然有f[i
][j]
=min
(f[i
+1][
j],d
p[i]
[i])
f[i]
[j]=
min(
f[i+
1][j
],dp
[i][
i]),g
g同理。
這樣單次詢問的複雜度就降到了o(n
2)o(
n2)。總時間複雜度就是o(t
n2)o
(tn2
)。而且區間dpd
p的常數好像還是122
1?
#include
#include
#include
using
namespace std;
const
int n=
1010
;int t,n,a[n]
,sum[n]
,dp[n]
[n],f[n]
[n],g[n]
[n];
intmain()
for(
int i=n-
1;i>=
1;i--
)for
(int j=i+
1;j<=n;j++
)printf
("%d\n"
,dp[1]
[n]);}
return0;
}
洛谷 P1430 序列取數
給出乙個序列,兩人輪流從一端開始取任意個數,最後所取數的和即為得分,兩人都想要較高得分,則先去者的最高得分是多少。首先不難想到用dp i j 表示序列剩下從i到j這段時的最高得分,這樣的話有n 2種狀態,n的狀態轉移,總複雜度為n 3,會t。因此可以考慮記錄下述值 le i j 表示從左邊開始取,剩...
洛谷P1430 序列取數
給定乙個長為n的整數序列 n 1000 由a和b輪流取數 a先取 每個人可從序列的左端或右端取若干個數 至少乙個 但不能兩端都取。所有數都被取走後,兩人分別統計所取數的和作為各自的得分。假設a和b都足夠聰明,都使自己得分盡量高,求a的最終得分。輸入格式 第一行,乙個正整數t,表示有t組資料。t 10...
洛谷P1430 序列取數
題目大意 給定乙個序列 s 每個人每輪可以從兩端 任選一端 取任意個數的整數,不能不取。在兩個人都足夠聰明的情況下,求先手的最大得分。題解 設 f 表示剩下 i,j 先手的最大得分。令 sum sum limits j s k therefore f sum min i f min limits j...