「模拟赛20181025」御风剑术 博弈论+DP简单优化
题目描述
Yasuo 和Riven对一排个假人开始练习。斩杀第个假人会得到个精粹。双方轮流出招,他们在练习中互相学习,所以他们的剑术越来越强。基于对方上一次斩杀的假人数量,可以斩杀掉剩余假人中位置最靠前的范围内数量的连续假人。最初Yasuo先出招,斩杀或个假人。Yasuo偷偷把你叫到一边,问在双方都采取最优策略的情况下, 他最多能够获取多少精粹。
输入
第一行一个正整数,表示假人的个数。
接下来行,每行一个正整数表示斩杀每个假人获得的精粹数。
输出
一个正整数表示 Yasuo 能够得到的最大精粹数量。
样例输入
5
1
3
1
7
2
样例输出
9
样例解释
Yasuo 斩号,Riven 斩号,Yasuo 斩号,Riven 斩号。
数据范围
对于前的数据,
对于前的数据,
对于的数据,
题解
首先,吐槽题目背景,并吐槽搬题并魔改的出题人。
简单博弈论,几乎不怎么涉及博弈论的知识。
显然两人其实是等价的,设表示现在剩下末尾的个假人,最后一刀是砍了个假人,能得到的最大值。显然我们可以枚举下一刀砍了多少人,状态的转移就会非常简单。但很遗憾,这样的复杂度是,并不能通过所有测试点。
考虑优化,我们把式子写下来吧:
,其中,表示后个人的之和。
化一下式子:
然后就没了……
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 5005
#define ll long long
#define inf (1ll << 50)
template<typename Mytype>void Read(Mytype &p)
{
p = 0;
char c = getchar();
for (; c < '0' || c > '9'; c = getchar());
for (; c >= '0' && c <= '9'; c = getchar())p = p * 10 + c - '0';
}
ll s[N];
ll f[5005][5005];
int n, A[N];
int main()
{
Read(n);
for (int i = 1; i <= n; i++)
Read(A[i]), s[n - i + 1] = A[i];
for (int i = 1; i <= n; i++)
s[i] += s[i - 1];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
ll ans1 = -inf, ans2 = -inf;
if (i >= (2 * j - 1))
ans1 = s[i] - f[i - (2 * j - 1)][2 * j - 1];
if (i >= (2 * j))
ans2 = s[i] - f[i - 2 * j][2 * j];
f[i][j] = max(max(ans1, ans2), f[i][j - 1]);
}
}
printf("%lld\n", f[n][1]);
}
作者:ModestStarlight
出处:http://www.cnblogs.com/ModestStarlight/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
分类:
动态规划 - 动态规划优化
, 数学 - 博弈论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现