如题。$N \leqslant 5000$。


感觉自己思路永远都是弯弯绕绕的。。即使会做也会被做繁掉。。果然还是我太菜了。


递减不爽,先倒序输入算了。第一问做个LIS没什么说的。第二问统计个数,考虑什么时候是重复计算的。$g[i]$表示第$i$个数结尾的LIS长度的方案(不重复)。当统计时dp到一个数时显然从前面满足$f_j+1=f_i且A_j<A_i$条件的累加过来,$A_j$不同的时候,自然不会有重复;当有相同的数且f一样时,如果这几种都加入,就重复了。而相同的几个数字显然靠后的方案统计到的更多,所以每次只取最靠右的那个数累加上去即可。实现上,开一个桶,记录vis,结束后再吐出来。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define _dbg(x,y) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+,M=<<,INF=0x3f3f3f3f;
int f[N],g[N],lis[N],a[N],vis[M],bin[N];
int n,len,ans,tot,cnt; int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
read(n);for(register int i=;i<=n;++i)read(a[n-i+]);
lis[len=]=INF;
for(register int i=;i<=n;++i){
f[i]=lower_bound(lis+,lis+len+,a[i])-lis;
if(f[i]>len)lis[++len]=a[i];else lis[f[i]]=a[i];
MAX(ans,f[i]);
}
for(register int i=;i<=n;++i){
if(f[i]==){g[i]=;continue;}
for(register int j=i-;j;--j)if(!vis[a[j]]&&a[j]<a[i]&&f[j]+==f[i])vis[bin[++tot]=a[j]]=,g[i]+=g[j];
while(tot)vis[bin[tot--]]=;
}
for(register int i=n;i;--i) if(!vis[a[i]]&&f[i]==ans)cnt+=g[i],vis[a[i]]=;
printf("%d %d\n",ans,cnt);
return ;
}

嗯这个是本人极其繁琐的想法。发现自己傻了有没有。。而且数据大的话桶不就挂了吗。。所以依据原来思路,改变对于dp状态的定义。$g[i]$表示第$i$个数结尾的长度为LIS的方案数,且不包括之前所有和自己相同且$len_{LIS}$相同的数的方案。这样每次转移时遇到相同即break。保证取的决策一定来源于上一个相同数和现在这个数之间。具体还是看code吧。。

另外还有一种做法是网络流。。不想写了QwQ。  ←不行,建边都会建炸掉

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define _dbg(x,y) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+,M=<<,INF=0x3f3f3f3f;
int f[N],g[N],lis[N],a[N];
int n,len,ans,tot,cnt; int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
read(n);for(register int i=;i<=n;++i)read(a[n-i+]);
lis[len=]=INF;
for(register int i=;i<=n;++i){
f[i]=lower_bound(lis+,lis+len+,a[i])-lis;
if(f[i]>len)lis[++len]=a[i];else lis[f[i]]=a[i];
MAX(ans,f[i]);
}
g[]=;
for(register int i=;i<=n;++i){
for(register int j=i-;~j;--j){
if(a[i]==a[j]&&f[i]==f[j])break;
if(f[i]==f[j]+&&a[j]<a[i])g[i]+=g[j];
}
}
for(register int i=;i<=n;++i)if(f[i]==ans)cnt+=g[i];
printf("%d %d\n",ans,cnt);
return ;
}

poj1952 BUY LOW, BUY LOWER[线性DP(统计不重复LIS方案)]的更多相关文章

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

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

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

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

  3. [POJ1952]BUY LOW, BUY LOWER

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

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

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

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

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

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

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

  7. Buy Low, Buy Lower

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

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

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

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

随机推荐

  1. 使用docker-client创建NFS挂载

    docker命令行挂载NFS如下: docker volume create --driver local --opt type=nfs --opt o=addr=192.168.11.129,rw ...

  2. 安卓渗透测试工具——Drozer(安装和使用)

    移动端渗透测试工具相比丰富的web端真的是少之又少,最近在做app的安全测试,用到了drozer,drozer的安装过程真的是太心酸了,中间报错了有6次才成功安装.. 一.环境准备 首先准备以下环境: ...

  3. 刷新页面后,让控制台的js代码继续执行

    在各种限时,秒杀活动中,有个自动循环的点击的工具是很重要的. 为了方便起见,我们把Js代码放在浏览器的控制台执行,但是刷新页面后,js代码就清空了,也就无法执行. 可以用js代码实现一个不受页面刷新影 ...

  4. 贪心+DFS:引水入城

    ...我觉得这道题放在贪心里应该不为过 原文:https://blog.csdn.net/qq_41513352/article/details/80726030 题目测评请点击——>https ...

  5. SpringMVC必备知识点汇总

    1.参数接收 1.1 数组 1.2 文件上传 1.2.1 单个文件上传 1.2.2 多个文件上传 1.2.3 文件上传时,携带其他数据 2.参数校验 参数校验:https://www.cnblogs. ...

  6. (5.8)mysql高可用系列——MySQL中的GTID复制(实践篇)

    一.基于GTID的异步复制(一主一从)无数据/少数据搭建 二.基于GTID的无损半同步复制(一主一从)(mysql5.7)基于大数据量的初始化 正文: [0]概念 [0.5]GTID 复制(mysql ...

  7. JavaScript中好用的对象数组去重

    对象数组去重 Demo数据如下: var items= [{ "specItems": [{ "id": "966480614728069122&qu ...

  8. linux 三剑客之sed常用总结

    sed 列出5-7行 [root@www ~]# nl /etc/passwd | sed -n '5,7p' -n不在处理前打印,搜索root,/p打印 nl /etc/passwd | sed ' ...

  9. c语言:<tchar.h>

    头文件“<tchar.h>”作用就是为了进行ASCII码和UNICODE(wide-character)码的头文件(该头文件由微软提供): 这样我们就可以使用TCHAR.H头文件中的定义的 ...

  10. python面向对象反射-框架原理-动态导入-元类-自定义类-单例模式-项目的生命周期-05

    反射 reflect 反射(reflect)其实是反省,自省的意思 反省:指的是一个对象应该具备可以检测.修改.增加自身属性的能力 反射:通过字符串获取对象或者类的属性,进行操作 设计框架时需要通过反 ...