日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【DP优化】【P1430】序列取数

發(fā)布時間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【DP优化】【P1430】序列取数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

傳送門

Description

給定一個長為n的整數(shù)序列,由A和B輪流取數(shù)(A先取)。每個人可從序列的左端或右端取若干個數(shù)(至少一個),但不能兩端都取。所有數(shù)都被取走后,兩人分別統(tǒng)計(jì)所取數(shù)的和作為各自的得分。假設(shè)A和B都足夠聰明,都使自己得分盡量高,求A的最終得分。

Input

第一行,一個正整數(shù)T,表示有T組數(shù)據(jù)。
接著T行,每行第一個數(shù)為n,接著n個整數(shù)表示給定的序列.

Output

輸出T行,每行一個整數(shù),表示A的得分

Sample Input

2 1 -1 2 1 2

Sample Output

-1 3

Hint

時限3s。
對于100%的數(shù)據(jù),\(n \leq 1000, T \leq 100\)

Solution

顯然是博弈DP。考慮設(shè)\(f_{i,j}\)是區(qū)間\([i,j]\)先手取數(shù)的最大答案。轉(zhuǎn)移顯然為
\(f_{i,j}=sum_j-sum_i-min{f_{k,j},f_{i,k}}\),其中滿足\(i~<~k~<~j\)。枚舉\(k\)進(jìn)行轉(zhuǎn)移,復(fù)雜度是\(O(n^3)\)。直接涼涼。
狀態(tài)已經(jīng)是\(O(n^2)\)無法優(yōu)化。考慮對轉(zhuǎn)移進(jìn)行優(yōu)化。考慮枚舉\(k\)是求一定區(qū)間內(nèi)\(f\)的最大值。這個\(f\)的區(qū)間是從小到大枚舉的,所以可以維護(hù)區(qū)間內(nèi)\(f\)的最大值。具體的,設(shè)\(l_{i,j}\)代表\(max{f_{i,k}}\)\(r_{i,j}\)代表\(max{f_{k,r}}\),其中滿足\(i~<~k~<~j\)
這樣轉(zhuǎn)移方程就變成\(f_{i,j}=sum_j-sum_i-min{l_{i,j},r_{i,j}}\)。這樣使用DP對DP進(jìn)行優(yōu)化,轉(zhuǎn)移變成\(O(1)\)的,可以通過本題。
其中\(l_{i,j}=max{l_{i,j-1},f_{i,j}}\)\(r\)的轉(zhuǎn)移同理。

Code

#include<cstdio> #include<cstring> #define rg register #define ci const int #define cl const long long inttypedef long long int ll;namespace IO {char buf[50]; }template<typename T> inline void qr(T &x) {char ch=getchar(),lst=' ';while(ch>'9'||ch<'0') lst=ch,ch=getchar();while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();if (lst=='-') x=-x; }template<typename T> inline void write(T x,const char aft,const bool pt) {if(x<0) {putchar('-');x=-x;}int top=0;do {IO::buf[++top]=x%10+'0';x/=10;} while(x);while(top) putchar(IO::buf[top--]);if(pt) putchar(aft); }template <typename T> inline T mmax(const T a,const T b) {if(a>b) return a;return b;} template <typename T> inline T mmin(const T a,const T b) {if(a<b) return a;return b;} template <typename T> inline T mabs(const T a) {if(a<0) return -a;return a;}template <typename T> inline void mswap(T &a,T &b) {T temp=a;a=b;b=temp;}const int maxn = 1010;int t,n; int MU[maxn],frog[maxn][maxn],lmax[maxn][maxn],rmax[maxn][maxn],sum[maxn];void clear();int main() {qr(t);while(t--) {clear() ;qr(n);for(rg int i=1;i<=n;++i) qr(MU[i]);for(rg int i=1;i<=n;++i) lmax[i][i]=rmax[i][i]=frog[i][i]=MU[i],sum[i]=sum[i-1]+MU[i];for(rg int i=1;i<n;++i) {for(rg int j=1;j<n;++j) {rg int r=i+j;if(r>n) break;frog[j][r]=sum[r]-sum[j-1]-mmin(0,mmin(lmax[j][r-1],rmax[j+1][r]));lmax[j][r]=mmin(frog[j][r],lmax[j][r-1]);rmax[j][r]=mmin(frog[j][r],rmax[j+1][r]);}}write(frog[1][n],'\n',true);}return 0; }void clear() {memset(MU,0,sizeof MU);memset(sum,0,sizeof sum);memset(frog,0,sizeof frog);memset(lmax,0,sizeof lmax);memset(rmax,0,sizeof rmax);n=0; }

Summary

在DP因?yàn)閺?fù)雜度較高而無法承受時,考慮對轉(zhuǎn)移進(jìn)行優(yōu)化。常見的如維護(hù)區(qū)間最大/最小值,通過數(shù)據(jù)結(jié)構(gòu)或者DP進(jìn)行優(yōu)化。

轉(zhuǎn)載于:https://www.cnblogs.com/yifusuyi/p/9570829.html

總結(jié)

以上是生活随笔為你收集整理的【DP优化】【P1430】序列取数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。