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

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

一个是方案数的求法:

设$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. 输出1~n中1的个数

    //输出1~n中1的个数,如f(1)=1,f(13)=6.通过测试,bymyself public class FindOnes{ public static void main(String arg ...

  2. OpenCV笔记(5)(定位票据并规范化、调库扫描文本)

    一.定位和变换票据 定位照片中的不规范票据或矩形文本,并将其变换为正规矩形,以供OCR识别. # -*- coding:utf-8 -*- __author__ = 'Leo.Z' import cv ...

  3. POJ 3061  Subsequence   尺取法   挑战146页

    ---恢复内容开始--- Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10487   Accept ...

  4. luoguP1041 传染病控制 x

    P1041 传染病控制 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染 ...

  5. [NOIP2014普及组T1]珠心算测验 - NTT

    求数组有多少个数,恰好等于集合中另外两个(不同的)数之和? 注意到数集比较小,而且涉及到下标的加法,可以很自然地想到卷积 注意减去自己加自己的贡献 真是一道NTT练手好题 #include <i ...

  6. JavaWeb_(SSH论坛)_五、帖子模块

    基于SSH框架的小型论坛项目 一.项目入门 传送门 二.框架整合 传送门 三.用户模块 传送门 四.页面显示 传送门 五.帖子模块 传送门 六.点赞模块 传送门 七.辅助模块 传送门 回复帖子 分析回 ...

  7. Unity3D_(游戏)卡牌04_游戏界面

        启动屏界面.主菜单界面.选关界面.游戏界面 卡牌01_启动屏界面 传送门 卡牌02_主菜单界面 传送门 卡牌03_选关界面 传送门 卡牌04_游戏界面    传送门 选关界面效果 (源代码在文 ...

  8. XCTF简单的php

    看看源码 <?php show_source(__FILE__); include("config.php"); $a=@$_GET['a']; $b=@$_GET['b'] ...

  9. 品 SpringBootApplication 注解源码

    @SpringBootApplication 由以下三个注解构成: @SpringBootConfiguration@EnableAutoConfiguration@ComponentScan 一:@ ...

  10. swift模式和模式匹配

    模式和模式匹配 模式: 代表单个或者复合值得结构,也就是说模式不是一个特定的值,它是一种抽象的结构,[一句话,不是特指,是泛指].这样就可以用模式来匹配各种各样的值. 例如:(x,y)可以匹配元祖(1 ...