1. 程式人生 > >Luogu P2734 遊戲 A Game 區間DP

Luogu P2734 遊戲 A Game 區間DP

註意 write pre lang str strong 裏的 var con

P2734 遊戲 A Game

題目背景

有如下一個雙人遊戲:N(2 <= N <= 100)個正整數的序列放在一個遊戲平臺上,遊戲由玩家1開始,兩人輪流從序列的任意一端取一個數,取數後該數字被去掉並累加到本玩家的得分中,當數取盡時,遊戲結束。以最終得分多者為勝。

題目描述

編一個執行最優策略的程序,最優策略就是使玩家在與最好的對手對弈時,能得到的在當前情況下最大的可能的總分的策略。你的程序要始終為第二位玩家執行最優策略。

輸入輸出格式

輸入格式:

第一行: 正整數N, 表示序列中正整數的個數。

第二行至末尾: 用空格分隔的N個正整數(大小為1-200)。

輸出格式:

只有一行,用空格分隔的兩個整數: 依次為玩家一和玩家二最終的得分。

輸入輸出樣例

輸入樣例#1:
6 
4 7 2 9 5 2
輸出樣例#1:
18 11

說明

題目翻譯來自NOCOW。

USACO Training Section 3.3

Solution

區間DP,註意題目說的最優策略是指,對第1個人和第2個人都是最優策略

f[i,j]表示i到j這一段先手的人的最優

可以得到f[i,j]=max{i+1..j裏的後手的最優+a[i],i..j-1裏的後手的最優+a[j]}

f[i,j]:=max(sum(a[i+1..j])-f[i+1,j]+a[i],sum(a[i..j-1])

-f[i,j-1]+a[j]);

sum用前綴和維護

 1 program w;
 2 uses math;
 3 const
 4   maxn=100;
 5 var
 6   i,j,n:longint;
 7   a,qian:array[0..maxn] of longint;
 8   f:array[0..maxn,0..maxn] of longint;
 9 
10 begin
11   readln(n);
12   for i:= 1 to n do
13   begin
14     read(a[i]);
15     qian[i]:=qian[i-1
]+a[i]; 16 end; 17 18 for i:= 1 to n do 19 f[i,i]:=a[i]; 20 21 for i:= n-1 downto 1 do 22 for j:= i to n do 23 f[i,j]:=max(qian[j]-qian[i]-f[i+1,j]+a[i],qian[j-1]-qian[i-1]-f[i,j-1]+a[j]); 24 25 writeln(f[1,n], ,qian[n]-f[1,n]); 26 end.

Luogu P2734 遊戲 A Game 區間DP