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的更多相关文章
- USACO Section 4.3 Buy low,Buy lower(LIS)
第一眼看到题目,感觉水水的,不就是最长下降子序列嘛!然后写……就呵呵了..要判重,还要高精度……判重我是在计算中加入各种判断.这道题比看上去麻烦一点,但其实还好吧.. #include<cstd ...
- POJ-1952 BUY LOW, BUY LOWER(线性DP)
BUY LOW, BUY LOWER Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 9244 Accepted: 3226 De ...
- 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 ...
- poj1952 BUY LOW, BUY LOWER【线性DP】【输出方案数】
BUY LOW, BUY LOWER Time Limit: 1000MS Memory Limit: 30000K Total Submissions:11148 Accepted: 392 ...
- 洛谷P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower
P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower 题目描述 “逢低吸纳”是炒股的一条成功秘诀.如果你想成为一个成功的投资者,就要遵守这条秘诀: "逢低吸纳,越低越 ...
- POJ 1952 BUY LOW, BUY LOWER 动态规划题解
Description The advice to "buy low" is half the formula to success in the bovine stock mar ...
- [POJ1952]BUY LOW, BUY LOWER
题目描述 Description The advice to "buy low" is half the formula to success in the bovine stoc ...
- BUY LOW, BUY LOWER_最长下降子序列
Description The advice to "buy low" is half the formula to success in the bovine stock mar ...
- POJ 1952 BUY LOW, BUY LOWER
$dp$. 一开始想了一个$dp$做法,$dp[i][j]$表示前$i$个数字,下降序列长度为$j$的方案数为$dp[i][j]$,这样做需要先离散化然后用树状数组优化,空间复杂度为${n^2}$,时 ...
随机推荐
- js图片放大境效果
放大境效果如下图所示,当鼠标放到小图时,就会出现浅黄色的小块,而右边方框也出现了,并且右边方框的内容时根据浅黄色小块的内容变换而变换: 原理: 1,准备2张图,一大一小,如上图所示,小图的盒子div1 ...
- 6-MySQL-Ubuntu-操作数据表的基本操作(一)
注: SQL语句的关键字不区分大小写,如select 和Select都可以 (1) 查看当前使用的数据库; select database(); (2) 使用某数据库或切换到某数据库 use 数据库名 ...
- Linux文件介绍
Linux文件介绍 Linux 文件属性 可以通过命令ll+文件名,查看文件的具体属性 例如:ll syz.gz 1736706 -rw-r--r--. 1 root root 28 Oct 27 1 ...
- 解决MSF更新证书错误
如下图所示提示签名无效下载失败,导致更新不了msf 解决办法如下: echo 'deb http://apt.metasploit.com/ lucid main' > /etc/apt/sou ...
- Tomcat7安装和配置以及优化
安装Tomcat7 下载安装方法一: 直接下载Tomcat7: wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-7/v7.0 ...
- AF_UNIX
3.SOCK_SEQPACKET SOCK_SEQPACKET提供一个顺序确定的,可靠的,双向基于连接的socket endpoint. 与SOCK_STREAM不同的是,它保留消息边界.(表明发送两 ...
- systemctl命令的使用及服务状态的查看
二.systemctl命令 systemctl list-units ##列出当前系统服务的状态 systemctl list-unit-files ##列出服务的开 ...
- 每天进步一点点-WPF-根据数据类型加载控件
目的,根据数据类型的不同,动态的加载适用于不同数据类型的控件(布局) 原理:为自定义的数据类型添加数据魔板,绑定的时候绑定这些数据类型的实例. 例子: 数据类型: 数据模板: <DataTemp ...
- Maven将本地项目打包后引入本地另一个项目
进入需要打包的文件夹,执行:mvn clean install -X 生成JAR包 打完JAR包后,将maven依赖安装 执行命令: install:install-file -Dfile=E:\co ...
- $My$ $template$(持续更新)
树链剖分:(来源:树的统计) #include<bits/stdc++.h> #define rint register int using namespace std; inline v ...