zoukankan      html  css  js  c++  java
  • 洛谷P1108 低价购买

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=5005;
     4 int n,len_ans=1,ans;
     5 int a[maxn],d[maxn],len[maxn],f[maxn];
     6 int search(int l,int r,int val)
     7 {
     8     while(l<r)
     9     {
    10         int mid=(l+r)>>1;
    11         if(d[mid]>val) l=mid+1;
    12         else r=mid;
    13     }
    14     return l;
    15 }
    16 int main()
    17 {
    18     scanf("%d",&n);
    19     for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    20     d[1]=a[1],len[1]=1;//d数组-利用单调性求最长下降子序列 len数组-以i为结尾的下降子序列最大长度 
    21     for(int i=2;i<=n;++i)
    22     {
    23         int pos=search(1,len_ans+1,a[i]);//利用单调性二分求len数组 
    24         len[i]=pos;d[pos]=max(d[pos],a[i]);
    25         len_ans=max(len_ans,pos);//求最长下降子序列 
    26     }
    27     //f数组 到达i位置的长度为len[i]的下降子序列(不一定是全局最长下降子序列) 的种类数 
    28     for(int i=1;i<=n;++i)
    29     {    
    30         if(len[i]==1) f[i]=1; 
    31         for(int j=1;j<i;++j)//f[i]等于f[j]之和 
    32                             //j在i位置以前 len[j]长度为len[i]-1 且 a[j]>a[i]
    33         {
    34             if(a[j]>a[i]&&len[j]==len[i]-1) f[i]+=f[j];
    35             if(a[i]==a[j]&&len[i]==len[j]) f[i]=0;//若i和j的数字相等且下降长度相等就置0 防止重复计算 
    36         }
    37         if(len[i]==len_ans) ans+=f[i];//若到该点的最大下降长度为全局最长下降长度就把该点方案数计入答案 
    38     } 
    39     printf("%d %d",len_ans,ans);
    40     return 0;
    41 }
  • 相关阅读:
    coredump分析
    Sword LRU算法
    C++ STL迭代器失效问题
    Sword DB主从一致性的解决方法
    Sword CRC算法原理
    C语言 按位异或实现加法
    Linux 等待信号(sigsuspend)
    C语言 宏定义之可变参数
    Linux shell字符串操作
    C++ *和&
  • 原文地址:https://www.cnblogs.com/yu-xing/p/10315311.html
Copyright © 2011-2022 走看看