ICPC2017网络赛(南宁)子序列最大权值(树状数组+dp)

来源:互联网 发布:vba聊天软件编程 编辑:程序博客网 时间:2024/05/20 04:49

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
  1. #include <stdio.h>  
  2. #include <math.h>  
  3. #include <stdlib.h>  
  4. #include <string.h>  
  5. #include <time.h>  
  6. #include <iostream>  
  7. #include <algorithm>  
  8. #include <string>  
  9. #include <queue>  
  10. #include <stack>  
  11. #include <vector>  
  12. #include <set>  
  13. #include <list>  
  14. #include <map>  
  15. #define mset(a,i) memset(a,i,sizeof(a))  
  16. using namespace std;  
  17. typedef long long ll;  
  18. const int INF=0x3f3f3f3f;  
  19. const int MAX=50005;  
  20. struct tree{  
  21.     int n;  
  22.     int a[MAX],Max[MAX],Min[MAX];//Max维护最大值 ,Min最小  
  23.     void init(int N)  
  24.     {  
  25.         n=N;  
  26.         for(int i=0;i<=N;i++)  
  27.             Max[i]=-(Min[i]=INF);  
  28.     }  
  29.     void update(int x,int num)//单点更新  
  30.     {  
  31.         a[x]=num;  
  32.         while(x<=n)  
  33.         {  
  34.             Min[x]=Max[x]=a[x];  
  35.             int lx=x&-x;  
  36.             for(int i=1;i<lx;i<<=1)  
  37.             {  
  38.                 Max[x]=max(Max[x],Max[x-i]);  
  39.                 Min[x]=min(Min[x],Min[x-i]);  
  40.             }  
  41.             x+=x&-x;  
  42.         }  
  43.     }  
  44.     int Qmax(int x,int y)//[x,y]最大值  
  45.     {  
  46.         int ans=-INF;  
  47.         while(y>=x)  
  48.         {  
  49.             ans=max(a[y], ans);  
  50.             y--;  
  51.             for(;y-(y&-y)>=x;y-=(y&-y))  
  52.                 ans=max(Max[y],ans);  
  53.         }  
  54.         return ans;  
  55.     }  
  56.     int Qmin(int x, int y)  
  57.     {  
  58.         int ans=INF;  
  59.         while(y>=x)  
  60.         {  
  61.             ans=min(a[y],ans);  
  62.             y--;  
  63.             for(;y-(y&-y)>= x; y-=(y&-y)  )  
  64.                 ans=min(Min[y],ans);  
  65.         }  
  66.         return ans;  
  67.     }  
  68. }C;  
  69. int a[303030];  
  70. int w[303030];  
  71. int main()  
  72. {  
  73.     int n=1;  
  74.     while(~scanf("%d",&a[n]))n++;n--;  
  75.     int top=0;  
  76.     for(int i=1;i<=n;i++)  
  77.     {  
  78.         if(a[i]<0)w[i]=0;  
  79.         else if(a[i]>10000){  
  80.             a[i]-=10000;  
  81.             w[i]=5;  
  82.         }  
  83.         else w[i]=1;  
  84.         a[i]+=21000;  
  85.         top=max(top,a[i]);  
  86.     }  
  87.     C.init(top);  
  88.     for(int i=1;i<=n;i++)  
  89.     {  
  90.         int dp=w[i]+C.Qmax(1,a[i]);//查询小的数的最大权值和  
  91.         C.update(a[i],dp);//更新a[i]时的最大值  
  92.     }  
  93.     printf("%d\n",C.Qmax(1,top));  
  94.     return 0;  
  95. }  


阅读全文
0 0