【USACO题库】3.3.5 A Game游戏

本文介绍了USACO竞赛中的一道题目,涉及到两人在序列两端取数的游戏,要求找出第一个人最优策略下的最大得分,保证对方也采用最优策略。通过动态规划的方法,设立状态转移方程解决此问题。样例输入和输出展示了具体的操作过程。

题目大意:

求在一个序列里(1<n<=100),两个人从序列的两端取数,第一个人最优策略的最优得分是多少(需保证第二个人也得是最优策略)


样例输入:

6

4 7 2 9 5 2

样例输出:

18 11

解释:

两人依次选的是:2,4,7,5,9,2

第一个人=2+7+9=18

第二个人=4+5+2=11



这道题实质上是一道动态规划类题目,因为两人所选的策略都是最优策略,并不是一个贪心策略。所以,我们可以想到把一个序列来分段,也就是当前两人分别在取的序列的开头和结尾来做一个分段——也就是设f[i,j]表示i~j这个区间里先手可以获得的最优值。

状态转移方程:

f[i,j]=sum[i,j]-min(f[i-1,j],f[i,j-1]);

sum[i,j]表示i~j这个区间里的总和;

f[i-1,j]表示先手取左边而后手可获得的最优值;

f[i,j-1]表示先手取右边而后手可获得的最优值;

f[i-1,j],f[i,j-1]两者之间的最小值就是当前先手应该取的位置。


边界:

f[i,i]=a[i](1<=i<=n)


代码:

var
        f,sum:array[0..100,0..100]of longint;
        n,i,j:longint;
        a:array[1..100]of longint;
function min(x,y:longint):longint;
begin
        if x<y then exit(x) else exit(y);
end;
procedure init;
begin
        fillchar(sum,sizeof(sum),0);
        for i:=1 to n-1 do
                for j:=i to n do
                        sum[i,j]:=sum[i,j-1]+a[j];
        for i:=1 to n do
                f[i,i]:=a[i];
end;
procedure work;
begin
        for i:=n-1 downto 1 do
                for j:=i+1 to n do
                        f[i,j]:=sum[i,j]-min(f[i,j-1],f[i+1,j]);
end;
begin
        readln(n);
        for i:=1 to n do
                read(a[i]);
        init;
        work;

        writeln(f[1,n],' ',sum[1,n]-f[1,n]);
end.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值