如果没有方案数的话,这道题水的不得了,裸的最长下降子序列。

但是它有方案数,所以...

一个是方案数的求法:

设$f[i]$是以$a[i]$结尾的最长下降子序列的长度,可以$n^2$$dp$出答案 如果$a[j]>a[i],1<=j<=i-1$,可以更新$f[i]=max(f[i],f[j]+1)$,这个额老生常谈了

设$s[i]$是以$a[i]$结尾的最长下降子序列的方案数,在更新$f[i]$的时候可以顺便更新$s[i]$:

如果$f[i]==f[j]+1$,那么$s[i]=s[j]$

如果$f[i]==f[j]$,那么$s[i]+=s[j]$

在得到最长下降子序列的长度为$len$之后,把所有$f[i]==len$的$s[i]$全部加起来,就是总的方案数。

但是,由于定义的是$s[i]$是以$a[i]$结尾的最长下降子序列的方案数,最长下降子序列的信息已经丢失,极有可能重复,比如:

3 2 1 3 2 1

后面那$3$个数的$s[]$都应该变为$0$
否则的话$1$,$2$,$3$构成了数列$321$,$1$,$2$,$6$也构成了数列$321$,计算方案数就重复了。

所以在两个位置$f[]$和$s[]$都相等的时候,就把那个位置置为$0$

这么做的话,那么这种情况会不会出锅呢:

6 5 4 6 5 3

是不会的,因为把后一个$5$的方案数置为$0$之后,$3$还可以从前一个$5$转移过来,如果让$3$从两个地方都累加上了答案,那才会出锅。

还有就是方案数会爆$long$ $long$,$_int128$也爆了,所以要用高精度。我直接用了封装成结构体的形式:

https://www.cnblogs.com/lyttt/p/11805335.html

(详见博客)

 //nice
/*
ID: Starry21
LANG: C++
TASK: buylow
*/
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<climits>
using namespace std;
#define N 5005
#define ML 505//MaxLenth
#define ll long long
#define INF 0x3f3f3f3f
struct BT//BigInt
{
int a[ML],len;
BT()//初始化
{
memset(a,,sizeof(a));
len=;
}
void Init()
{
a[]=;
}
BT operator + (const BT &A)const
{
BT B;
B.len=max(len,A.len);
for(int i=;i<B.len;i++)
{
B.a[i]+=A.a[i]+a[i];
if(B.a[i]>=)
{//进位 9+9=18 进位不会超过10
B.a[i]-=;
B.a[i+]++;
}
}
if(B.a[B.len])//进到了下一位
B.len++;
return B;
}
void read()
{
char d[ML];
scanf("%s",d);
int l=strlen(d);
for(int i=;i<l;i++)
a[i]=d[l-i-]-'';
len=l;
}
void write()
{
for(int i=len-;i>=;i--)
printf("%d",a[i]);
}
};
ll rd()
{
ll f=1ll,x=;char c=getchar();
while(c<''||c>''){if(c=='-') f=-;c=getchar();}
while(c>=''&&c<=''){x=(x<<)+(x<<)+(c^);c=getchar();}
return f*x;
}
int n;
ll a[N];
int f[N];
BT s[N];
int main()
{
//freopen("buylow.in","r",stdin);
//freopen("buylow.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++)
a[i]=rd();
/*
后面统计答案,是f[i]==max_long的s[i]全部加起来
如果出现重复的 那个地方的s[]应该为0
3 2 1 3 2 1
后面那3个数的s[]都应该为0
如果一来就赋了初值1 答案就会错
*/
s[].Init(),a[]=LONG_MAX;
for(int i=;i<=n;i++)
{
for(int j=i-;j>=;j--)
if(a[j]>a[i])
f[i]=max(f[i],f[j]+);
for(int j=i-;j>=;j--)
{//记录方案数
if(a[j]>a[i]&&f[i]==f[j]+) s[i]=s[i]+s[j];
if(a[i]==a[j]&&f[i]==f[j]) break;
/*
防止重复
3 2 1 3 2 1
3 2 1是本质相同的序列
是为了防止第6个数向第2个数转移的情况
*/
}
}
ll t1=;BT t2;
for(int i=;i<=n;i++)
{
if(f[i]>t1)
t1=f[i],t2=s[i];
else if(f[i]==t1) t2=t2+s[i];
}
printf("%lld ",t1);
t2.write();
puts("");
return ;
}

Code

USACO4.3 Buy Low, Buy Lower【简单dp·高精度】的更多相关文章

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

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

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

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

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

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

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

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

  5. [POJ1952]BUY LOW, BUY LOWER

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

  6. Buy Low, Buy Lower

    Buy Low, Buy Lower 给出一个长度为N序列\(\{a_i\}\),询问最长的严格下降子序列,以及这样的序列的个数,\(1 <= N <= 5000\). 解 显然我们可以很 ...

  7. 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 ...

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

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

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

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

随机推荐

  1. 各种环境下搭建ruby on rails开发环境

    win10上搭建raby on rails环境: 步骤如下 1.安装ruby (我选择的版本是ruby 2.2.3p173) 2.安装rails gem 在这之前建议先把gem的源换成淘宝的源,速度快 ...

  2. Django框架简介(1)

    目录 手写web框架 基于wsgiref模块写web服务端框架 python三大主流框架 django框架介绍 注意事项 django下载方法 django项目及app的创建 命令行创建项目 pych ...

  3. Open Cascade:计算体积

    TopoDS_Shape shape; ... GProp_GProps System; BRepGProp::LinearProperties(shape, System); BRepGProp:: ...

  4. Fermat小定理的证明

    本证明参考了李煜东老师<算法竞赛进阶指南>. 我们首先证明欧拉定理,然后推导出费马小定理. 欧拉定理:若\(\gcd(a,n)=1,a,n\in \mathbb{Z}\),则\(a^{\p ...

  5. TensorFlow使用记录 (一): 基本概念

    基本使用 使用graph来表示计算任务 在被称之为Session的上下文中执行graph 使用tensor表示数据 通过Variable维护状态 使用feed和fetch可以为任意的操作(op)赋值或 ...

  6. 【HDOJ5943】Kingdom of Obsession(数论)

    题意:给定n个人,n个座位,人的编号是[1,n],座位的编号是[s+1,s+n],编号为i的人能坐在编号为j的座位上的条件是j%i=0 问是否存在一组方案使得座位和人一一对应 n,s<=1e9 ...

  7. python解析字体反爬

    爬取一些网站的信息时,偶尔会碰到这样一种情况:网页浏览显示是正常的,用python爬取下来是乱码,F12用开发者模式查看网页源代码也是乱码.这种一般是网站设置了字体反爬 一.58同城 用谷歌浏览器打开 ...

  8. HDU 2829 [Lawrence] DP斜率优化

    解题思路 首先肯定是考虑如何快速求出一段铁路的价值. \[ \sum_{i=1}^k \sum_{j=1, j\neq i}^kA[i]A[j]=(\sum_{i=1}^kA[i])^2-\sum_{ ...

  9. DIY Arduino 方向盘

    之前的项目中使用Arduino做UE4的输入设备时候需要用到UE4Duino这个插件,以字符串的形式从Arduino中组装信息并发送到串口,使用UE4Duino进行解析,过程比较麻烦. 最近发现的一个 ...

  10. Android_(服务)Vibrator振动器

    Vibrator振动器是Android给我们提供的用于机身震动的一个服务,例如当收到推送消息的时候我们可以设置震动提醒,也可以运用到游戏当中增强玩家互动性 运行截图: 程序结构 <?xml ve ...