您的位置:首页 > 其它

【算法学习笔记】33.在线算法 SJTU OJ 1006 求和游戏

2015-04-23 01:56 267 查看

1006. 求和游戏

Description

石柱上有一排石头键盘,每个键上有一个整数。请你在键盘上选择两个键,使这两个键及其之间的键上的数字和最大。如果这个最大的和不为正,则输出“Game Over"。

Input Format

第1行:键的个数n。

第2..n+1行:键上的数字整数 ai。

−100≤ai≤100

对于70%的数据,2≤n≤1,000

对于100%的数据,2≤n≤1,000,000

Output Format

一行,最大和或者”Game Over"。

Sample Input

5
3
-5
7
-2
8

Sample Output

13

Sample Input

3
-6
-9
-10

Sample Output

Game Over


这个题和之前关于求最大子列和的文章非常相似,但是又有不同,因为这是一个应用题...它要求至少要有两个键才行,所以最小的子序列也要保证长度大于等于2.

那么在这种情况下,我们原来的在线算法就不能直接使用了.

这里有两个新的在线算法来完成这个问题, 一个是专门为这个问题而改良的,一个是全新的思路可以解决原问题和这个新问题.

新在线算法1:
  核心思想依然是:遇到了负数可以进行重置当前和. 但是在驱动的过程中要考虑到始终保持最小长度为2,所以要不断的错位来完成这件事情.
再处理的过程中,我们所需要决策的就是i一定是要续接上的,至于头部是继续上一次的,还是它的前一个位置 只需比较一下大小即可.
如果n[i-1]比当前的和大, 那么就从它开始续接不就好啦~ 如果当前和更大, 那就要继续下去
代码如下:[/code]

int main()
{
int num(0);
cin >> num;
int result(0);
int total(0), smallest(32785);
//smalest 表示的是从第一个数开始 的 连续子序列和最小的时候的那个和 也就是以某一个数为尾端
//total 表示的是从 第一个数 开始 到 现在 为止的所有数的和 也就是以现在为尾端
//两者相减就是 从smallest结尾 到现在为止的子序列和 然后用result来维护最大值
for (int i = 0, temp; i < num; ++i)
{
cin >> temp;
total += temp;
//result =  max(result, total-smallest)
//在此处由于smallest维护的是到前2个数为止的
//那么相减的结果必然会至少包含前一个数
if (result < total - smallest)
result = total - smallest;
//smallest = min(smallest, total-temp )
//此处维护的smallest是从第一个数到当前数的前2个数的
//因为i饿total - temp 其实是到i-1为止的total
if (smallest > total - temp)
smallest = total - temp;
}
if (result > 0) cout << result << endl;
else cout << "Game Over\n";
}


View Code
补充链接:
http://blog.csdn.net/hcbbt/article/details/10454947 六种方法解决连续子序列最大和
http://www.cnblogs.com/txd0u/p/3353355.html 1006题解


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐