1. 程式人生 > >洛谷P3004 [USACO10DEC]寶箱Treasure Chest

洛谷P3004 [USACO10DEC]寶箱Treasure Chest

自己 values 輸出 names art his sid class data-

P3004 [USACO10DEC]寶箱Treasure Chest

題目描述

Bessie and Bonnie have found a treasure chest full of marvelous gold coins! Being cows, though, they can‘t just walk into a store and buy stuff, so instead they decide to have some fun with the coins.

The N (1 <= N <= 5,000) coins, each with some value C_i (1 <= C_i <= 5,000) are placed in a straight line. Bessie and Bonnie take turns, and for each cow‘s turn, she takes exactly one coin off of either the left end or the right end of the line. The game ends when there are no coins left.

Bessie and Bonnie are each trying to get as much wealth as possible for themselves. Bessie goes first. Help her figure out the maximum value she can win, assuming that both cows play optimally.

Consider a game in which four coins are lined up with these values:

30 25 10 35

Consider this game sequence:

Bessie Bonnie New Coin

Player Side CoinValue Total Total Line

Bessie Right 35 35 0 30 25 10

Bonnie Left 30 35 30 25 10

Bessie Left 25 60 30 10

Bonnie Right 10 60 40 --

This is the best game Bessie can play.

貝西和伯尼找到了一個裝滿了金幣的寶箱!但是,作為奶牛,他們不能隨便進入一家商店去買東西。所以他們決定去用這些金幣玩一個遊戲。

這裏有N(1<=N<=5000)個硬幣,每個都有一個價值C_i(1<=C_i<=5000)。這些硬幣被擺成了一行。貝西和伯尼每人一回合。到了一只奶牛的回合時,他就要拿走最左邊或者最右邊的硬幣。當沒有硬幣時,遊戲結束。

貝西和伯尼都想要使自己拿到的金幣價值盡量高,貝西先拿。現在貝西想要你幫幫她,算出她最多可以拿多少錢(伯尼也會盡量取到最優)。

輸入輸出格式

輸入格式:

  • Line 1: A single integer: N

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

輸出格式:

  • Line 1: A single integer, which is the greatest total value Bessie can win if both cows play optimally.

輸入輸出樣例

輸入樣例#1:
4 
30 
25 
10 
35 
輸出樣例#1:
60 
技術分享
/*
    區間dp 
    f[i][j]表示在i,j這段區間內先手能獲得的最大分數;
    那麽後手在先手最優方案走法下,按最優方案走的最大分數就是
    i,j這個區間總分數減去f[i][j].
*/
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 5010
int w[maxn],sum[maxn],f[maxn][maxn],n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&w[i]);
        sum[i]=sum[i-1]+w[i];
        f[i][i]=w[i];
    }
    for(int len=2;len<=n;len++){
        for(int l=1;l+len-1<=n;l++){
            int r=l+len-1;
            f[l][r]=sum[r]-sum[l-1]-min(f[l][r-1],f[l+1][r]);
        }
    }
    printf("%d",f[1][n]);
}
二維dp 技術分享
#include<iostream>
#include<cstdio>
#define maxn 5010
using namespace std;
int n,sum[maxn],f[maxn];
int main(){
    scanf("%d",&n);
    int x;
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        sum[i]=sum[i-1]+x;
        f[i]=x;
    }
    for(int len=2;len<=n;len++)
        for(int l=1;l+len-1<=n;l++){
            int r=l+len-1;
            f[l]=sum[r]-sum[l-1]-min(f[l+1],f[l]);
        }
    printf("%d",f[1]);
}
一維dp

洛谷P3004 [USACO10DEC]寶箱Treasure Chest