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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

JZOJ 1322. 硬币游戏

發(fā)布時(shí)間:2025/3/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JZOJ 1322. 硬币游戏 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Description

  FJ的奶牛喜歡玩硬幣游戲,所以FJ發(fā)明了一個(gè)新的硬幣游戲。一開始有N(5<=N<=2,000)個(gè)硬幣堆成一疊,從上往下數(shù)第i個(gè)硬幣有一個(gè)整數(shù)值C_i(1<=C_i<=100,000)。
  兩個(gè)玩家輪流從上倒下取硬幣,玩家1先取,可以從上面取1個(gè)或2個(gè)硬幣,下一輪的玩家可以取的硬幣數(shù)量最少為1個(gè),最多為上一個(gè)玩家取的數(shù)量的2倍,硬幣全部取完比賽結(jié)束。
  已知玩家2絕頂聰明,會(huì)采用最優(yōu)策略,現(xiàn)在請(qǐng)你幫助玩家1,使得玩家1取得的硬幣值的和最大。

Input

  第一行輸入N
  第二至N+1行每行輸入一個(gè)整數(shù)C_i

Output

  輸出玩家1能獲得的最大值。

Sample Input

5
1
3
1
7
2

Sample Output

9

Solution

  • 這題顯然是一道博弈題(“絕頂聰明”),但是傳統(tǒng)的搜索過不了這么大的極限數(shù)據(jù)。

  • 觀察到目標(biāo)是求極值,于是我們考慮動(dòng)態(tài)規(guī)劃。

  • 設(shè) F[i][j] 表示還剩余 i 個(gè)硬幣、上一次對(duì)手選了 j 個(gè)硬幣的最大獲利。

  • 再設(shè) sum[i][j] 表示從 ij 的價(jià)值和(可以用前綴和維護(hù))。

  • 那么可得轉(zhuǎn)移方程式:

    F[i][j]=max{sum[i?k+1][i]+(sum[1][i?k]?F[i?k][k])}

  • 其中:

  • sum[i?k+1][i] 表示本次自己拿走第 i 枚硬幣的錢數(shù)和;
  • sum[1][i?k]?f[i?k][k] 表示在剩下的局面中自己還能拿的錢數(shù)和;
  • 1kmin(2?k,i)
  • 于是我們將上式化簡(jiǎn),得:

    F[i][j]=max{sum[1][i]?F[i?k][k]}?(1kmin(2?k,i))

  • 但然而這樣的 DP 是 O(N3) 的,極限數(shù)據(jù)會(huì)時(shí)間超限,要想辦法優(yōu)化成 O(N2) 的。

  • 繼續(xù)觀察上式,發(fā)現(xiàn)兩個(gè)相鄰狀態(tài) F[i][j]F[i][j?1] 有很多重復(fù)的轉(zhuǎn)移,

  • 代入可以發(fā)現(xiàn)只有兩個(gè)狀態(tài)是有用的,即:當(dāng) k=2?jk=2?j?1 時(shí)有意義。

  • 那么只轉(zhuǎn)移兩個(gè)狀態(tài),時(shí)間復(fù)雜度就是 O(N2) ,成功通過本題。

Code

#include<cstdio> using namespace std; const int N=2001; int sum[N],f[N][N]; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } inline int max(int x,int y) {return x>y?x:y; } int main() {int n=read();for(int i=1;i<=n;i++) sum[n-i+1]=read();for(int i=1;i<=n;i++) sum[i]+=sum[i-1];for(int i=1;i<=n;i++)for(int j=1;j<=n-i+1;j++){/*for(int k=1;k<=2*j && k<=i;k++)f[i][j]=max(f[i][j],sum[i]-f[i-k][k]); N^3做法 */f[i][j]=f[i][j-1];int k=2*j-1;if(i>=k) f[i][j]=max(f[i][j],sum[i]-f[i-k][k]);if(i>=++k) f[i][j]=max(f[i][j],sum[i]-f[i-k][k]);}printf("%d",f[n][1]);return 0; }

總結(jié)

以上是生活随笔為你收集整理的JZOJ 1322. 硬币游戏的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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