SDUT 2870 都--两端取数游戏 动态规划

本文解析了一个经典的博弈论编程问题,涉及A、B两人轮流从序列两端取数的策略游戏。通过动态规划算法求解最优策略下两者的最大得分,展示了如何初始化和更新状态矩阵,最终输出A、B两人的得分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接
题目大意
A、B两个人轮流从一个序列中取数,每次只能取走两端的数,A先取,每次都采用最优策略,问最终A、B两人所能取到的最大数分别是多少

# include <bits/stdc++.h>
using namespace std;
# define MAXN 110
int N;
int data[MAXN];///存放初始值
int sum[MAXN];///存放前i个数的和
int gain[MAXN][MAXN];///从区间[i,j]取数的最大值
int main()
{
    while(cin>>N)
    {
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=N;i++)
        {
            cin>>data[i];
            sum[i]=sum[i-1]+data[i];
            gain[i][i]=data[i];///初始化
        }
        for(int i=N-1;i>0;i--)///动态规划,从小区间扩展到大区间
        {
            for(int j=i;j<=N;j++)
            {
                gain[i][j]=sum[j]-sum[i-1]-min(gain[i+1][j],gain[i][j-1]);
                ///sum[j]-sum[i-1]代表[i,j]区间所有数的和
                ///当前人从[i,j]区间取数,那么下一个人只能从[i+1,j]或者
                ///[i,j-1]区间取数
            }
        }
        cout<<gain[1][N]<<' '<<sum[N]-gain[1][N]<<endl;
    }
    return 0;
}
### 关于 SDUT Fun 5 组合计算 #### 解题思路和方法 组合是指从 \( n \) 个不同元素中出 \( m \) 个元素的组合方式的量,通常记作 \( C(n, m) \)[^1]。对于给定的问题描述,在实现过程中需要注意输入据范围以及算法效率。 为了高效地解决这个问题,可以采用动态规划的方法来预处理并存储较小规模下的组合值,从而避免重复计算带来的性能开销。具体来说: - 使用二维组 `C` 来保存已经计算过的组合结果; - 初始化边界条件:当零个元素时只有一种情况即什么都不选;当所目等于总目时也仅存在一种全选的情况; - 对于其他情形,则通过递推关系式 \( C[n][m]=C[n−1][m]+C[n−1][m−1] \) 进行填充表格中的剩余位置[^3]。 下面是基于上述思想的一个优化版本代码示例: ```c #include <stdio.h> #define MAXN 20 // 定义最大值为题目限定的最大n值加一 int comb[MAXN+1][MAXN+1]; void initComb() { int i, j; for(i = 0; i <= MAXN; ++i){ comb[i][0] = comb[i][i] = 1; for(j = 1; j < i; ++j) comb[i][j] = comb[i-1][j] + comb[i-1][j-1]; } } int main(){ int N, n, m; initComb(); // 预先计算好所有的组合 scanf("%d", &N); while(N--){ scanf("%d %d", &n, &m); if(m > n || n < 0 || m < 0){ printf("Invalid input\n"); continue; } printf("%d\n", comb[n][m]); } return 0; } ``` 此程序首先初始化了一个用于储存组合的结果表,并利用循环结构完成了对整个表内所有可能值的一次性求解过程。之后读入多组测试案例的据并对每一组分别输出对应的组合结果[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值