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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

傳送門

Description

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

Input

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

Output

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

Sample Input

2 1 -1 2 1 2

Sample Output

-1 3

Hint

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

Solution

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

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因為復雜度較高而無法承受時,考慮對轉移進行優化。常見的如維護區間最大/最小值,通過數據結構或者DP進行優化。

轉載于:https://www.cnblogs.com/yifusuyi/p/9570829.html

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。