1. 程式人生 > >洛谷P2964 [USACO09NOV]硬幣的遊戲A Coin Game

洛谷P2964 [USACO09NOV]硬幣的遊戲A Coin Game

ima sin 兩枚 bar each player rom mem when

P2964 [USACO09NOV]硬幣的遊戲A Coin Game

題目描述

Farmer John‘s cows like to play coin games so FJ has invented with a new two-player coin game called Xoinc for them.

Initially a stack of N (5 <= N <= 2,000) coins sits on the ground; coin i from the top has integer value C_i (1 <= C_i <= 100,000).

The first player starts the game by taking the top one or two coins (C_1 and maybe C_2) from the stack. If the first player takes just the top coin, the second player may take the following one or two coins in the next turn. If the first player takes two coins then the second player may take the top one, two, three or four coins from the stack. In each turn, the current player must take at least one coin and at most two times the amount of coins last taken by the opposing player. The game is over when there are no more coins to take.

Afterwards, they can use the value of the coins they have taken from the stack to buy treats from FJ, so naturally, their purpose in the game is to maximize the total value of the coins they take. Assuming the second player plays optimally to maximize his own winnings, what is the highest total value that the first player can have when the game is over?

MEMORY LIMIT: 20 MB

農夫約翰的奶牛喜歡玩硬幣遊戲.

初始時,一個有N枚硬幣的堆棧放在地上,從堆頂數起的第i枚硬幣的幣值 為Ci

開始玩遊戲時,第一個玩家可以從堆頂拿走一枚或兩枚硬幣.如果第一個玩家只拿走堆頂的 一枚硬幣,那麽第二個玩家可以拿走隨後的一枚或兩枚硬幣.如果第一個玩家拿走兩枚硬幣,則第二個玩家可以拿走1,2,3,或4枚硬幣.在每一輪中,當前的玩家至少拿走一枚硬幣,至多拿 走對手上一次所拿硬幣數量的兩倍.當沒有硬幣可拿時,遊戲結束.

兩個玩家都希望拿到最多錢數的硬幣.請問,當遊戲結束時,第一個玩家最多能拿多少錢 呢?

輸入輸出格式

輸入格式:

  • Line 1: A single integer: N

  • Lines 2..N+1: Line i+1 contains a single integer: C_i

輸出格式:

  • Line 1: A single integer representing the maximum value that can be made by the first player.

輸入輸出樣例

輸入樣例#1:
5 
1 
3 
1 
7 
2 
輸出樣例#1:
9 

說明

There are five coins with the values 1, 3, 1, 7, and 2.

The first player starts by taking a single coin (value 1). The opponent takes one coin as well (value 3). The first player takes two more coins (values 1 and 7 -- total 9). The second player gets the leftover coin (value 2-- total 5).

技術分享
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 2010
int n,st[maxn],ans,sum[maxn];
void dfs(int pre,int who,int from,int mx){
    ans=max(ans,mx);
    if(from==n+1)return;
    for(int i=1;i<=min(pre*2,n-from+1);i++){
        if(who==0)dfs(i,1,from+i,mx);
        if(who==1)dfs(i,0,from+i,max(mx,sum[from+i-1]-sum[from-1]));
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&st[i]);
        sum[i]=sum[i-1]+st[i];
    }
    ans=max(sum[1],sum[2]);
    dfs(1,0,2,sum[1]);
    dfs(2,0,3,sum[2]);
    cout<<ans;
}
10分 暴力 技術分享
/*
    1.狀態:建立一個二維的狀態(i,j)說明拿硬幣的權力到達其中一名玩家時,桌面上還剩下編號為1~i(倒序,1為最底下的) 的硬幣,
    上一名玩家拿走了j枚硬幣。 
    2.下一步的狀態:那麽這一個玩家在這一輪可以選擇拿走1,2,3,4…2*j枚硬幣,而他所能獲得的最大硬幣面值就是1~i所有的硬幣面
    值之和減去他完成此次操作後(設他取走了k枚硬幣)到達狀態(i-k,k)的另一名玩家所能獲得的最大硬幣數。 
    3.狀態的轉移:可是因為k的取值範圍很大,所以不能直接枚舉,不難發現(i,j-1)和(i,j)的狀態只相差兩種選擇的可能,即下一步取走
    2*j-1或2*j個硬幣的這兩種,只需要再比較一次這兩種狀態即可。 
    **狀態轉移方程:dp[i][j]=max(dp[i][j],sum[i]-dp[i-k][k],sum[i]-dp[i-k-1][k+1])(k==2*j-1);
    4.答案:答案則是在剩下1~n枚硬幣時(初始狀態)的dp[n][1](下一步可以選擇1枚或兩枚硬幣)了。 
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 2010
int n,sum[maxn],c[maxn],dp[maxn][maxn]; //數組要開大一點,不然會WA; 
int main(){
    cin>>n;
    for(int i=n;i>=1;i--)cin>>c[i];//為了處理方便,我們直接逆序輸入(編號自底向上) 
    for(int i=1;i<=n;i++)sum[i]+=sum[i-1]+c[i];//獲取前綴和 
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            dp[i][j]=dp[i][j-1];//重合部分 
            int k=2*j-1;
            if(k<=i)dp[i][j]=max(dp[i][j],sum[i]-dp[i-k][k]);//新增狀態 
            k++;
            if(k<=i)dp[i][j]=max(dp[i][j],sum[i]-dp[i-k][k]);//新增狀態 
        }
    cout<<dp[n][1]<<endl;
    return 0;
}
100分 dp

洛谷P2964 [USACO09NOV]硬幣的遊戲A Coin Game