您的位置:首页 > 理论基础 > 计算机网络

L. The Heaviest Non-decreasing Subsequence Problem -最长不降子序列变形nlogn-2017 ACM-ICPC 亚洲区(南宁赛区)网络赛

2017-09-24 16:42 483 查看
Let SSS
be a sequence of integers s1s_{1}s​1​​,s2s_{2}s​2​​,.........,sns_{n}s​n​​
Each integer is is associated with a weight by the following rules:

(1) If is is negative, then its weight is 000.

(2) If is is greater than or equal to 100001000010000,
then its weight is 555.
Furthermore, the real integer value of sis_{i}s​i​​
is si−10000s_{i}-10000s​i​​−10000
. For example, if sis_{i}s​i​​
is 101011010110101,
then is is reset to 101101101
and its weight is 555.

(3) Otherwise, its weight is 111.

A non-decreasing subsequence of SSS
is a subsequence si1s_{i1}s​i1​​,si2s_{i2}s​i2​​,.........,siks_{ik}s​ik​​,
with i1<i2 ... <iki_{1}<i_{2}\ ...\ <i_{k}i​1​​<i​2​​ ... <i​k​​,
such that, for all 1≤j<k1 \leq j<k1≤j<k,
we have sij<sij+1s_{ij}<s_{ij+1}s​ij​​<s​ij+1​​.

A heaviest non-decreasing subsequence of SSS
is a non-decreasing subsequence with the maximum sum of weights.

Write a program that reads a sequence of integers, and outputs the weight of its

heaviest non-decreasing subsequence. For example, given the following sequence:

808080757575737373939393737373737373101011010110101979797−1-1−1−1-1−1114114114−1-1−1101131011310113118118118

The heaviest non-decreasing subsequence of the sequence is
<73,73,73,101,113,118><73, 73, 73, 101, 113, 118><73,73,73,101,113,118>
with the total weight being 1+1+1+5+5+1=141+1+1+5+5+1 = 141+1+1+5+5+1=14.
Therefore, your program should output 141414
in this example.

We guarantee that the length of the sequence does not exceed
2∗1052*10^{5}2∗10​5​​

Input Format

A list of integers separated by blanks:s1s_{1}s​1​​,s2s_{2}s​2​​,.........,sns_{n}s​n​​

Output Format

A positive integer that is the weight of the heaviest non-decreasing subsequence.

样例输入

80 75 73 93 73 73 10101 97 -1 -1 114 -1 10113 118


样例输出

14


/*
题意:
给你一个数列,当该数数值<0时该数无价值,
当该数数值>=10000时 该数值-=10000,其价值为5,
其余情况价值为1
问价值和最大的非降子序列是多少

题解:
价值可以转换为长度
>=10000的数,就在数组中存5次
<0的数因为没价值,并且求得是子序列不是子串,不影响最后序列的选取,所以根本不用存
最后求得的长度即为答案
*/

#include <bits/stdc++.h>
#include <cstdio>

using namespace std;

int a[1000010];
int f[1000010];
int d[1000010];

int _bsearch(const int *f, int len, const int &a)
{
int l = 0, r = len - 1;
while(l <= r)
{
int mid = (l + r) / 2;
if(a >= f[mid - 1] && a < f[mid])
return mid;
else if(a < f[mid])
r = mid - 1;
else
l = mid + 1;
}
}

int LIS(const int *a, const int &n)
{
int i,j,len = 1;
f[0] = a[0];
d[0] = 1;
for(i = 1; i < n; i++)
{
if(a[i] < f[0])
j = 0;
else if(a[i] >= f[len - 1])
j = len++;
else
j = _bsearch(f, len, a[i]);
f[j] = a[i];
d[i] = j + 1;
}

return len;
}

int main()
{
int temp;
int len = 0;

while(cin>>temp)
{
if(temp > 0 && temp < 10000)
{
a[len++] = temp;
}
else if(temp >= 10000)
{
for(int i = 0; i < 5; i++)
a[len++] = temp - 10000;
}
}
int ans = LIS(a,len);
cout<<ans<<endl;

return 0;
}

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