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

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

一个是方案数的求法:

设$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. Axure 日期函数详解

    时间函数详解 Now     根据计算机系统设定的日期和时间返回当前的日期和时间值.如:设置元件文本的值为:[[Now]]:输出:Mon Jan 08 2018 10:42:55 GMT+0800 ( ...

  2. 零拷贝的原理及Java实现

    在谈论Kafka高性能时不得不提到零拷贝.Kafka通过采用零拷贝大大提供了应用性能,减少了内核和用户模式之间的上下文切换次数.那么什么是零拷贝,如何实现零拷贝呢? 什么是零拷贝 WIKI中对其有如下 ...

  3. dlerror和dlclose用法

    dlclose() 1. 包含头文件 #include<dlfcn.h> 2. 函数定义  int dlclose(void *handle) dlclose用于关闭指定句柄的动态链接库, ...

  4. Hibernate 缓存机制详细分析

    在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别)以及查询缓存,当然还要讨论下我们的N+1的问题. 随笔虽长,但我相 ...

  5. springmvc手动渲染jsp

    因为需要MockHttpServletResponse对象来得到输出的内容,要引入的包 <dependency> <groupId>org.springframework< ...

  6. Luogu P4707 重返现世 (拓展Min-Max容斥、DP)

    题目链接 https://www.luogu.org/problem/P4707 题解 最近被神仙题八连爆了-- 首先Min-Max容斥肯定都能想到,问题是这题要用一个扩展版的--Kth Min-Ma ...

  7. @vue/cli 3.x 版本配置productionGzip提高性能

    第一步:安装插件 npm i -D compression-webpack-plugin 第二步:引入.在文件vue.config.js里导入compression-webpack-plugin,并添 ...

  8. C++入门经典-例2.10-控制输出精确度

    1:代码如下: // 2.10.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...

  9. eclipse中设置tab为4个空格

    1.insert space for tabs前打勾 2.General settings中选择Spaces only 3.搞定

  10. LeetCode 116/117. 填充同一层的兄弟节点(Populating Next Right Pointers in Each Node)

    题目描述 给定一个二叉树 struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } 填充 ...