10891 - Game of Sum(DP)
2015-09-18 09:51
232 查看
一开始自己尝试着写,将状态表示成d[i][j][k]表示当前区间i~j,轮到k取数时的最优解,但是我并没有定义清楚这个最优解的含义,导致出现了错误。
其实状态方程的意义应该是固定的,所以要定义一个统一意义的含义。 所以我如果仍然要这样表示状态,那么它的含义应该是:当前区间i~j,轮到k取数时k能获得的最大和。
那么可以发现,其实这个第三维是没有意义的,因此可以省略 。 并且这可以等价于给对方剩下和尽量小的序列。 所以状态转移就显而易见了。
细节参见代码:
其实状态方程的意义应该是固定的,所以要定义一个统一意义的含义。 所以我如果仍然要这样表示状态,那么它的含义应该是:当前区间i~j,轮到k取数时k能获得的最大和。
那么可以发现,其实这个第三维是没有意义的,因此可以省略 。 并且这可以等价于给对方剩下和尽量小的序列。 所以状态转移就显而易见了。
细节参见代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 105; const int INF = 1000000000; int n,m,a[maxn],d[maxn][maxn],kase=0,vis[maxn][maxn],sum[maxn]; int dp(int i, int j) { int& ans = d[i][j]; if(vis[i][j] == kase) return ans; vis[i][j] = kase; int m = 0; for(int k = i+1; k <= j; k++) m = min(m,dp(k,j)); for(int k = i; k < j; k++) m = min(m,dp(i,k)); ans = sum[j] - sum[i-1] - m; return ans; } int main() { while(~scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) scanf("%d",&a[i]), sum[i] = sum[i-1] + a[i]; ++kase; printf("%d\n",2 * dp(1,n) - sum ); } return 0; }
相关文章推荐
- IntelliJ IDEA启动自动进入最后一个项目
- linux启动执行某个脚本
- Eclipse装插件的几种方式
- 一个资深iOS开发者对于React Native的看法
- 剑指Offer系列---(26)二叉搜索树的后序遍历序列
- 更新xcode7运行程序,报错*** Assertion failure in -[UIApplication _runWithMainScene:transi
- 人际关系的确是一项资产
- String类中toCharArray()方法的用法
- 2015 9月18日 工作计划与执行
- KVM虚拟机安装使用教程(Ubantu)
- spring中缓存的了解及学习
- JQuery Mobile Popup窗口定位
- Service生命周期与使用
- JQuery Mobile Popup窗口定位
- Mysql远程连接失败原因(数据库在linux;持续更新中。。。)
- 使用Maven编译项目遇到——“maven编码gbk的不可映射字符”解决办法
- 动态级联菜单
- Web网页性能管理详解
- ASP.NET中GridView控件删除数据的两种方法
- Guava(三):流畅的排序