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 ...
随机推荐
- LeetCode.1122-相对排序数组(Relative Sort Array)
这是小川的第393次更新,第427篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第258题(顺位题号是1122).给定两个数组arr1和arr2,arr2中的元素是不同的 ...
- 面试题:检测一个ip的真实性,如果真实,确定其是不是在某一范围内
例题: 现有一个ip 10.2.1.71 ,检测该ip是否为真实有效的ip,并判断该ip是否在10.2.1.1——10.2.1.255之间 解题思路:用正则表达式检测ip的真实性,如果真实,将该ip转 ...
- login 模块,re 模块
标准三流 标准输入流:sys. stdin # input的底层 标准输出流:sys. stdout # print的底层 标准错误流:sys. stderr # 异常及loggin ...
- CornerNet 算法笔记
论文名称:CornerNet: Detecting Objects as Paired Keypoints 论文链接:https://arxiv.org/abs/1808.01244 代码链接:htt ...
- 使用URLOS在linux系统中极速部署NFS共享存储服务
如何在linux系统里搭建NFS服务?其实我们只需要安装一个URLOS面板,然后就能在3分钟内将NFS服务部署完成.近日,URLOS在应用市场中上架了一款NFS应用,它可以让我们的节点主机在3分钟内极 ...
- sqlalchemy的常用字段
#encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,\ Float,Boolean,DECIMAL, ...
- VBnet窗口获取键盘输入
https://blog.csdn.net/youyoulg/article/details/39120669 C# WinFrom捕获按键按下事件(一) https://blog.csdn.net/ ...
- jenkins自动化部署springboot
一.linux按jar包名称部署 1.执行shell PID=$(ps -ef | grep app.jar | grep -v grep | awk '{ print $2 }') if [ -z ...
- Swagger中paramType
paramType:表示参数放在哪个地方 header-->请求参数的获取:@RequestHeader(代码中接收注解) query-->请求参数的获取:@RequestPa ...
- Hadoop系列读书笔记
<Hadoop应用架构>是Orilley旗下精品系列的图书 Hadoop序列化 Thrift 不支持内部压缩 不能分片 缺少MapReduce的原生支持 Protocol Buffers ...