A game——hihoCoder173

本文解析了一道360春季招聘中的算法题,通过动态规划求解两个玩家轮流从数组两端取值的最大得分。代码实现考虑了数组长度的奇偶性,并根据轮次确定取值策略。

这个题目是今年360春招的题目,这是链接

用的是动态规划,先上代码:

int n;
int a[1010], dp[1010][1010];

int main(){
    cin>>n;
    for(int i = 0; i<n; i++){
        cin>>a[i];
    }
    if(n&1){
        for(int i = 0; i<n; i++)
            dp[i][i] = a[i];
    }
    
    for(int i = 1; i<n; i++){
        for(int j = 0; j+i<n; j++){
            if(((n+i)&1) == 0){
                dp[j][j+i] = min(dp[j+1][j+i], dp[j][j+i-1]);
            }else{
                dp[j][j+i] = max(dp[j+1][j+i] + a[j], dp[j][j+i-1] + a[j+i]);
            }
        }
    }
    
    cout<<dp[0][n-1];
    return 0;
}

在链接里的解释说明的很清楚了,这里添加以下解释:

1、dp[ i ][ j ]指的是在区间 i-j 范围内A能取到的最大值

2、第一个(n&1),即判断n的奇偶性。(dp[i][i]是初值,即为区间为1)当n是奇数时,说明A会拿到最后一个元素,故在此区间内(区间长度为1时)A能取到的最大值即为该元素的值,于是需要赋值给dp的初值;而当n为偶数时,A拿不到最后一个元素,故在此区间(区间长度为1)A能取到的最大值为0,故dp的初值为0(不赋初值)

3、(n+I)&1意为该B取值,反之则为轮到A取值


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值