https://nanti.jisuanke.com/t/17319
Let SS be a sequence of integers s_{1}s
1
, s_{2}s
2
, ......, s_{n}s
n
Each integer is is associated with a weight by the following rules:
(1) If is is negative, then its weight is 00.
(2) If is is greater than or equal to 1000010000, then its weight is 55. Furthermore, the real integer value of s_{i}s
i
is s_{i}-10000s
i
−10000 . For example, if s_{i}s
i
is 1010110101, then is is reset to 101101 and its weight is 55.
(3) Otherwise, its weight is 11.
A non-decreasing subsequence of SS is a subsequence s_{i1}s
i1
, s_{i2}s
i2
, ......, s_{ik}s
ik
, with i_{1}<i_{2}\ ...\ <i_{k}i
1
<i
2
... <i
k
, such that, for all 1 \leq j<k1≤j<k, we have s_{ij}<s_{ij+1}s
ij
<s
ij+1
.
A heaviest non-decreasing subsequence of SS 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:
8080 7575 7373 9393 7373 7373 1010110101 9797 -1−1 -1−1 114114 -1−1 1011310113 118118
The heaviest non-decreasing subsequence of the sequence is <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=14. Therefore, your program should output 1414 in this example.
We guarantee that the length of the sequence does not exceed 2*10^{5}2∗10
5
Input Format
A list of integers separated by blanks:s_{1}s
1 , s_{2}s
2 ,......,s_{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
题目来源
2017 ACM-ICPC 亚洲区(南宁赛区)网络赛
【题意】:
给出一组数列,负数的价值为0,,>=10000的价值为5,但值要减掉1万,其余的数价值为1;
问,选一个不减子序列,使得价值和最大,并输出这个价值
【分析】:
每加入一个新元素,用前面的,小数,最大权值加上当前元素的权值,作为当前元素的最优权值。
别的队的同学用拆点,把权值为5的点拆成5个1,跑一边最长不减子序列就可以
【代码】:
[cpp] view plain copy
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <list>
#include <map>
#define mset(a,i) memset(a,i,sizeof(a))
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAX=50005;
struct tree{
int n;
int a[MAX],Max[MAX],Min[MAX];//Max维护最大值 ,Min最小
void init(int N)
{
n=N;
for(int i=0;i<=N;i++)
Max[i]=-(Min[i]=INF);
}
void update(int x,int num)//单点更新
{
a[x]=num;
while(x<=n)
{
Min[x]=Max[x]=a[x];
int lx=x&-x;
for(int i=1;i<lx;i<<=1)
{
Max[x]=max(Max[x],Max[x-i]);
Min[x]=min(Min[x],Min[x-i]);
}
x+=x&-x;
}
}
int Qmax(int x,int y)//[x,y]最大值
{
int ans=-INF;
while(y>=x)
{
ans=max(a[y], ans);
y--;
for(;y-(y&-y)>=x;y-=(y&-y))
ans=max(Max[y],ans);
}
return ans;
}
int Qmin(int x, int y)
{
int ans=INF;
while(y>=x)
{
ans=min(a[y],ans);
y--;
for(;y-(y&-y)>= x; y-=(y&-y) )
ans=min(Min[y],ans);
}
return ans;
}
}C;
int a[303030];
int w[303030];
int main()
{
int n=1;
while(~scanf("%d",&a[n]))n++;n--;
int top=0;
for(int i=1;i<=n;i++)
{
if(a[i]<0)w[i]=0;
else if(a[i]>10000){
a[i]-=10000;
w[i]=5;
}
else w[i]=1;
a[i]+=21000;
top=max(top,a[i]);
}
C.init(top);
for(int i=1;i<=n;i++)
{
int dp=w[i]+C.Qmax(1,a[i]);//查询小的数的最大权值和
C.update(a[i],dp);//更新a[i]时的最大值
}
printf("%d\n",C.Qmax(1,top));
return 0;
}