【P2964】硬币的游戏(DP+前缀和)
2024-10-21 18:37:00
一道DP,思维难度真是不小。
首先对于这个题的数据,我们可以发现差不多可以支持n^2logn,但是貌似也不会有这种复杂度的线性DP(至少这个题看上去不是这样)。所以我们考虑N^2做法。因为求得是价值和,所以很明显要使用前缀和。
我们用f[i][j]来表示从下往上i枚硬币时轮到第一个人选,上一次对方取了j枚硬币时的情况。则根据题意这个人此时能取t枚(t<=i),此时这个人可以去那么此时取到的最大值就是max(f[i][j],f[i-t][t])。又因为t的数目确实比较庞大,无法一个个枚举,所以考虑是否可以转移,容易看出,f[i][j]与f[i][j-1]能取的只差了j×2和j×2-1这两种状态,所以可以摒弃循环而直接用if判断来转移。
代码实际上还是比较短的:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define re register
using namespace std;
int f[][],a[],s[],n,m;
int main()
{
cin>>n;
for(re int i=n;i>=;i--) cin>>a[i];
for(re int i=;i<=n;i++) s[i]=s[i-]+a[i];
for(re int i=;i<=n;i++)
{
for(re int j=;j<=n;j++)
{
f[i][j]=f[i][j-];
int t=*j-;
if(t<=i)
f[i][j]=max(f[i][j],s[i]-f[i-t][t]);
t++;
if(t<=i)
f[i][j]=max(f[i][j],s[i]-f[i-t][t]);
}
}
cout<<f[n][];
}
最新文章
- c++使用stdint.h和inttypes.h
- 虚拟机软件bochs编译使用问题
- iOS 注意事项
- nyoj------20吝啬的国度
- 学习IT技术的技巧
- Android studio使用smack连接xmpp服务器收发消息
- windows系统安装securtCRT
- 本地安装plsql和instantclient连接linux服务器端的oracle
- Filebeat插件启动失败,不能直接查找报错原因
- php通过CURL模拟post提交请求
- js 执行机制
- [转]Ubuntu 16.04安装有道词典
- 安装最新nginx
- 用Python开发Zeroc Ice应用
- Delphi XE 6,Rad Studio XE 6 官方下载(附破解)
- DIV+CSS规范命名集合
- 【Python系列】python关键字、符号、数据类型等分类
- Node学习HTTP模块(HTTP 服务器与客户端)
- 仿LOL项目开发第九天
- Qt 4.8.5 icpc: Command not found