Buy Low, Buy Lower

给出一个长度为N序列\(\{a_i\}\),询问最长的严格下降子序列,以及这样的序列的个数,\(1 <= N <= 5000\)。

解

显然我们可以很轻易地求出严格下降子序列,思维的过程应该是从熟悉走向不熟悉,从自然走向不自然,因此还是照搬老套路,设\(f_i\)表示以i结尾的最长严格下降子序列的长度,\(g_i\)表示这样的序列的方案数。

接着我们发现,方案之所以不能照搬转移,关键在于结尾有多个相同的数,它们的方案发生了叠加,再仔细研究,你会发现,最靠近i的数必然包括了所有的方案,于是我们只要桶排就可以做到寻找最近的数。

注意到数字可能很大,于是可以事先离散化,而且此题需要打高精度,然后就可以做了。

参考代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define il inline
#define ri register
#define Size 5010
using namespace std;
struct lll{
int num[75];
il lll(){clear();}
il void clear(){
memset(num,0,sizeof(num));
num[0]|=true;
}
il void read(){
string s;cin>>s,num[0]=s.size();
for(ri int i(1);i<=num[0];++i)
num[i]=s[num[0]-i]-48;
}
il void print(){
for(int i(num[0]);i;--i)
putchar(num[i]+48);
putchar('\n');
}
il bool operator!(){
return num[0]==1&&num[1]==0;
}
il void operator=(string s){
num[0]=s.size();
for(ri int i(1);i<=num[0];++i)
num[i]=s[num[0]-i]-48;
}
il lll operator+(lll x){
lll y;y.clear();ri int i;
for(i=1;i<=num[0]||i<=x.num[0];++i){
y.num[i]+=num[i]+x.num[i];
if(y.num[i]>9)y.num[i]-=10,++y.num[i+1];
}if(i>1&&!y.num[i])--i;return y.num[0]=i,y;
}
il void operator+=(lll x){
ri int i;
for(i=1;i<=num[0]||i<=x.num[0];++i){
num[i]+=x.num[i];if(num[i]>9)num[i]-=10,++num[i+1];
}while(i>1&&!num[i])--i;num[0]=i;
}
}fp[Size];
struct lsh{
int a[Size],b[Size],n;
il int look(int x){
return b[x];
}
il void prepare(int x,int ar[]){
n=x;
for(ri int i(1);i<=n;++i)
a[i]=ar[i];sort(a+1,a+n+1);
for(ri int i(1);i<=n;++i)
b[i]=dfs(ar[i]);
}
il int dfs(int x){
int l(1),r(n),mid;
while(l<=r){
mid=l+r>>1;
if(a[mid]<x)l=mid+1;
else r=mid-1;
}return l;
}
}L;
bool b[Size];
int a[Size],dp[Size];
il void read(int&);
int main(){
int n;read(n);
for(int i(1);i<=n;++i)read(a[i]);
L.prepare(n,a),a[++n]=-1;
for(int i(1),j;i<=n;++i){
memset(b,0,sizeof(b));
for(j=i-1;j;--j)
if(a[j]>a[i]){
if(dp[j]>dp[i])
dp[i]=dp[j],fp[i]=fp[j],
b[L.look(j)]|=true;
else if(dp[i]==dp[j]&&!b[L.look(j)])
fp[i]+=fp[j],b[L.look(j)]|=true;
}
++dp[i];if(!fp[i])fp[i]="1";
}printf("%d ",dp[n]-1),fp[n].print();
return 0;
}
il void read(int &x){
x&=0;ri char c;while(c=getchar(),c<'0'||c>'9');
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
}

Buy Low, Buy Lower的更多相关文章

  1. USACO Section 4.3 Buy low,Buy lower(LIS)

    第一眼看到题目,感觉水水的,不就是最长下降子序列嘛!然后写……就呵呵了..要判重,还要高精度……判重我是在计算中加入各种判断.这道题比看上去麻烦一点,但其实还好吧.. #include<cstd ...

  2. POJ-1952 BUY LOW, BUY LOWER(线性DP)

    BUY LOW, BUY LOWER Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 9244 Accepted: 3226 De ...

  3. USACO 4.3 Buy Low, Buy Lower

    Buy Low, Buy Lower The advice to "buy low" is half the formula to success in the stock mar ...

  4. poj1952 BUY LOW, BUY LOWER【线性DP】【输出方案数】

    BUY LOW, BUY LOWER Time Limit: 1000MS   Memory Limit: 30000K Total Submissions:11148   Accepted: 392 ...

  5. 洛谷P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower

    P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower 题目描述 “逢低吸纳”是炒股的一条成功秘诀.如果你想成为一个成功的投资者,就要遵守这条秘诀: "逢低吸纳,越低越 ...

  6. POJ 1952 BUY LOW, BUY LOWER 动态规划题解

    Description The advice to "buy low" is half the formula to success in the bovine stock mar ...

  7. [POJ1952]BUY LOW, BUY LOWER

    题目描述 Description The advice to "buy low" is half the formula to success in the bovine stoc ...

  8. BUY LOW, BUY LOWER_最长下降子序列

    Description The advice to "buy low" is half the formula to success in the bovine stock mar ...

  9. POJ 1952 BUY LOW, BUY LOWER

    $dp$. 一开始想了一个$dp$做法,$dp[i][j]$表示前$i$个数字,下降序列长度为$j$的方案数为$dp[i][j]$,这样做需要先离散化然后用树状数组优化,空间复杂度为${n^2}$,时 ...

随机推荐

  1. Spring Boot Restful WebAPI集成 OAuth2

    系统采用前后端分离的架构,采用OAuth2协议是很自然的事情. 下面开始实战,主要依赖以下两个组件: <dependency> <groupId>org.springframe ...

  2. 天道神诀---FTP服务

    FTP 2种模式 主动模式(默认) 客户端以1024-65535之间某一端口发送指令到服务端的21端口,并建立连接.服务端接受到以后,以20端口去连接客户端,建立一条新的链接并传输数据 被动模式 客户 ...

  3. 笔记45 Hibernate快速入门(二)

    Hibernate O/R 映射 一.多对一 一个Product对应一个Category,一个Category对应多个Product,所以Product和Category是多对一的关系.使用hiber ...

  4. 1、Go语言的介绍

    一.概念 Go语言(Golang)是云计算时代的C语言,使用Go编译的程序可以媲美C/C++代码的速度,而且更加安全.支持并行进程. 二.Go语言的优势 1.部署简单.可以直接编译成机器码,不依赖其他 ...

  5. 【RabbitMQ】六种模式与SpringBoot整合

    添加rabbitmq的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...

  6. 最大字段和--GSS1 MUSHROOM ORZ

    过于naive了= =作为一个知识点总结一下算了.主要就是合并.对于一个区间的最大字段和,可以分别事下面的两个区间的子段和,或者事左边的右边加右边的左边.然后搞一下 = = #include < ...

  7. NX二次开发-UFUN参数选择对话框UF_UI_select_parameters

    #include <uf.h> #include <uf_ui.h> #include <uf_modl.h> UF_initialize(); //参数选择对话框 ...

  8. NX二次开发-UFUN设置工程图PNG图片长度UF_DRF_set_image_width

    #include <uf.h> #include <uf_drf.h> UF_initialize(); //插入PNG char* file_name = "D:\ ...

  9. NX二次开发-UFUN设置除工作层之外的所有图层的状态UF_LAYER_set_all_but_work

    NX11+VS2013 #include <uf.h> #include <uf_ui.h> #include <uf_layer.h> UF_initialize ...

  10. [JZOJ 5861] 失意

    思路: 求交集最大老套路,排序之后用堆维护即可. #include <bits/stdc++.h> using namespace std; const int mod = 1e9+7; ...