poj1952 BUY LOW, BUY LOWER[线性DP(统计不重复LIS方案)]
如题。$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方案)]的更多相关文章
- poj1952 BUY LOW, BUY LOWER【线性DP】【输出方案数】
BUY LOW, BUY LOWER Time Limit: 1000MS Memory Limit: 30000K Total Submissions:11148 Accepted: 392 ...
- POJ-1952 BUY LOW, BUY LOWER(线性DP)
BUY LOW, BUY LOWER Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 9244 Accepted: 3226 De ...
- [POJ1952]BUY LOW, BUY LOWER
题目描述 Description The advice to "buy low" is half the formula to success in the bovine stoc ...
- USACO Section 4.3 Buy low,Buy lower(LIS)
第一眼看到题目,感觉水水的,不就是最长下降子序列嘛!然后写……就呵呵了..要判重,还要高精度……判重我是在计算中加入各种判断.这道题比看上去麻烦一点,但其实还好吧.. #include<cstd ...
- 洛谷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 ...
- Buy Low, Buy Lower
Buy Low, Buy Lower 给出一个长度为N序列\(\{a_i\}\),询问最长的严格下降子序列,以及这样的序列的个数,\(1 <= N <= 5000\). 解 显然我们可以很 ...
- 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 ...
- BUY LOW, BUY LOWER_最长下降子序列
Description The advice to "buy low" is half the formula to success in the bovine stock mar ...
随机推荐
- PJzhang:国外主流站点钓鱼网站示例工具shellphish
猫宁!!! 参考链接:https://www.uedbox.com/post/58583/ 这个是这个项目的github地址 https://github.com/thelinuxchoice/she ...
- ORACLE 左连接 右连接 内连接 外连接 全连接 五中表连接方式
1.左连接 :left join 2.右连接:right join 3.内连接:inner join 4.外连接:outer join 5.全连接:full join
- jmeter-ERROR o.a.j.p.j.c.DataSourceElement: JDBC data source already defined for: 报错原因
转载自:https://www.cnblogs.com/zhangfeivip/p/9450403.html Jmeter 多个threadgroup 中的配置元件会一次性进行初始化 例如3个th ...
- ZooKeeper常用命令行操作
ZooKeeper常用命令行操作 通过./zkCli.sh 打开zk的客户端进入命令行后台 ls/ls2 列出当前节点下的子节点 ls2还会列出当前节点的状态 [zk: localhost:2181( ...
- Go语言中的数组(九)
我刚接触go语言的数组时,有点不习惯,因为相对于JavaScript这样的动态语言里的数组,go语言的数组写起来有点不爽. 定义数组 go语言定义数组的格式如下: ]int var 数组名 [数组长度 ...
- %300为0的个数(牛客第四场)-- number
题意: 给你一串数,问你如题. 思路: 我不是这样的作法,从后往前,先取00,再算%3==0的个数,往前推的时候有递推关系: #define IOS ios_base::sync_with_stdio ...
- thinkphp6下无法获取header头中的Authorization(apache版)
今天遇到在thinkphp框架中获取不到header头里边的 Authorization ,后来在.htaccess里面加多一项解决,记录下: <IfModule mod_rewrite.c&g ...
- win10自带虚拟机的使用(Hyper-v)
昨天刚发现的觉得特别好用,故推荐一下,跟VM虚拟机的使用方法是一样的 1.点击开始菜单中的<设置>图标,进入设置页码 2.点击<应用>图标,进入应用页码,并找到程序和功能 3. ...
- TCP/IP 协议是如何保证数据可靠性的?
原文: 网络基础:TCP协议-如何保证传输可靠性 TCP协议传输的特点主要就是面向字节流.传输可靠.面向连接.这篇博客,我们就重点讨论一下TCP协议如何确保传输的可靠性的. 确保传输可靠性的方式TCP ...
- springboot2.X版本得@Transactional注解事务不回滚不起作用
参考文章 https://my.oschina.net/happyBKs/blog/1624482 https://blog.csdn.net/u011410529/article/detail ...