HOJ 3087 Discover's Problem I

Discover's Problem I

 

Submitted : 31, Accepted : 14

Given a sequence , how to find the longest increasing subsequence? I think, almost all of you will think it's a piece of cake. Here comes a question about the increasing subsequence, and I think you will like it. Now you don't need to pay attention to the length but to the sum of its elements. You should find out the increasing subsequence that the sum of its elements is max and print the sum of this increasing subsequence’s elements. 

Input

The first line contains a integer T, indicating there a T cases(T<=10). Every case begin with a integer n, which is the length of the sequence. ( 1<=n<=10^5).The next line comes the elements . The values of it's elements are positive integers that no more than 2^31-1. 

Output

For every case, print the answer in a single line. 

Sample Input 

2
5
100 1 2 2 3
5
9 3 4 10 5

Sample output

100
19

题目大意:给你一列数共n个(1<=n<=10^5),求最大的上升和序列。

分析:树状数组+DP 或则 线段树+DP现在我们先讲一下:树状数组+DP实际上状态转移方程是很容易想出的,dp[i]=max(dp[j])+a[i](其中0<j<i)关键是如何降低复杂度来实现快速的寻找最大的前i-1项中的最大上升和子序列。现在来说明一下如何用树状数组来实现快速的查询:按数的大小从小到大的排一下序,然后再按照数字的大小插入这样就保证了已经插入的就一定比插入的小,那么单调递增就能保证了,现在还一个需要确保,就是先后问题。由于树状数组如果按照排序前的序号插入的话,那么我们只统计他们的序号前面的就同样可以保证先后问题,仔细想一想其实没那么难的。

我们来寻找一下此问题的本源思想。我们是求上升且最大的子序列和,那么问题来了上升且最大,二这两个又不是单调的关系,无论怎样我们的快速查找的方法都只是一个排序的标准即一个判断条件。因此我们就想办法了,如果先确定一个不就OK了,寻找区间最大的方法是有的,因此我们就想方法先把单调升序列确定,然后查询区间的最大值。让序列在查询的过程中保持升序列的确很难想,现在介绍一下实际具体的做法:

1.设结构体,包含两个变量:数值,下标

2.按照数值从小到大的规则排序

3.遍历排序后的序列,按照结构体中的下标插入树状数组中:求出树状数组中插入位置前的最大的递升序列和,加上当前结构体中的数值再插入

4.遍历求出最大值关键是树状数组如何操作,下面还是不理解记住吧!

代码如下

/*
 * File:   main.cpp
 * Author: Administrator
 *
 * Created on 2012年3月11日, 下午6:21
 */

#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX = 100001;
long long a[MAX];
long long dp[MAX];

/*
 * 这个是DP的思想,但是要实现DP还需一定的技巧
 */
int lowbit(int x) {
    return x & (-x);
}

void add(int x, long long p) {
    while (x < 100001) {
        a[x] = max(p, a[x]);
        x += lowbit(x);
    }
}

long long sum(int x) {
    long long res = 0;
    while (x) {
        res = max(res, a[x]);
        x -= lowbit(x);
    }
    return res;
}

struct node {
    int pos;
    int element;

    bool operator<(const node & a)const {
        if (element != a.element) {
            return element < a.element;
        }
        return pos > a.pos;
    }
} Node[MAX];

int main() {
    int T;
    int n;
    while (scanf("%d", &T) != EOF) {
        while (T--) {
            scanf("%d", &n);
            memset(dp, 0, sizeof (dp));
            memset(a, 0, sizeof (a));
            for (int i = 1; i <= n; i++) {
                scanf("%d", &Node[i].element);
                Node[i].pos = i;
            }
            sort(Node + 1, Node + n + 1);
            for (int i = 1; i <= n; i++) {
                dp[Node[i].pos] = sum(Node[i].pos) + (long long)(Node[i].element);
                add(Node[i].pos, dp[Node[i].pos]);
            }
            long long res = 0;
            for (int i = 1; i <= n; i++) {
                res = max(dp[i], res);
            }
            printf("%lld\n", res);
        }
    }
    return 0;
}

 

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值