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}$,时 ...
随机推荐
- 《深入理解Java虚拟机》- 重载与重写
这一节打算从“方法调用”的主题进行分析. 方法调用并不等同于方法执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还不设计方法内部的具体运行过程. 一.概念 解析调用:所有 ...
- hdu6321 /// 状压DP
题目大意: 将一个 顶点不重复的边 的边集称为图中的matching 在一个n个点的零图中进行m次操作 + u v为在u v之间加一条边 存在重边 - u v为去掉u v之间的一条边 每次操作后 输出 ...
- C static extern和全局变量
#include <stdio.h> //默认全局变量为外部变量 int a; //当全局变量前面加上static时,该变量为内部变量 static int b; void test(); ...
- 2018-8-10-wpf-DoEvents-
title author date CreateTime categories wpf DoEvents lindexi 2018-08-10 19:16:51 +0800 2018-2-13 17: ...
- drop,delete与truncate的区别
drop直接删掉表 truncate删除表中数据,再插入时自增长id又从1开始 delete删除表中数据,可以加where字句. (1) DELETE语句执行删除的过程是每次从表中删除一行,并且同时将 ...
- 第二天:PowerShell别名
1.查询别名: Get-Alias -name ls Get-Alias -name dir Get-Alias -name fl Get-Alias -name ft 2.查看可用的别名 查看可用的 ...
- BCZM: Chapter 1
1.1 CPU 占用率 https://www.cnblogs.com/TenosDoIt/p/3242910.html 1.2 中国象棋将帅 https://blog.csdn.net/kabini ...
- ACM-ICPC 训练平台 & 比赛 分析
the file can download in https://pan.baidu.com/s/1HwoLFHGAG-boQbIn9xIhxA occ5 the article is also pu ...
- python编程语言学习day02
格式化输出 (1)info 格式 (2)%字符串占位 %s 表示字符串占位 %d 表示整数占位 %f 表示浮点数占位 中间的% 之后是所需要输入的值 多个占位, % 之后用()括号括起 ...
- JS分支结构与循环结构
1.分支结构 ①if语句 语法结构 if (/* 条件表达式 */) { // 执行语句 } if (/* 条件表达式 */){ // 成立执行语句 } else { // 否则执行语句 } ...