POJ 1952 Buy Low,Buy Lower
2016-07-13 20:03
337 查看
题目大意:
求最长下降子序列及其个数(严格的…..)
分析:
求最长上升子序列很简单大家都会,那么方案数呢??记得之前做过一道题求的是最短路的计数,那道题是在更新最短路径时更新其对应方案数,这道题是不是也可以这样做呢?所以我们定义num[i]代表前i个数中最长子序列的个数,如果f[i]=f[j]+1(i>j)就代表i可以由j转移而来,所以j的方案数目包含在i中,那么num[i]=num[i]+num[j]。有了怎么转移,我们还要考虑一个严肃的问题,怎么去重??
看下面一段代码:
这是什么意思呢??O(≧口≦)O
我们还是规定i>j,如果a[i]=a[j](因为我们是倒着往前找的)就代表我们不需要再往前枚举更新方案数目了,因为j之前的方案数目已经包含在j中了,而如果f[i]=1这代表什么呢??代表i前面没有比它大的数,那么显然f[j]也应该等于1,就是说ij方案数完全相同,这么来说如果我们保留i的方案数目,那么就会和j重复,而又因为i在j的后面所以我们显然是要保留j而把i的方案数目清零
代码如下:
by >o< neighthorn
求最长下降子序列及其个数(严格的…..)
分析:
求最长上升子序列很简单大家都会,那么方案数呢??记得之前做过一道题求的是最短路的计数,那道题是在更新最短路径时更新其对应方案数,这道题是不是也可以这样做呢?所以我们定义num[i]代表前i个数中最长子序列的个数,如果f[i]=f[j]+1(i>j)就代表i可以由j转移而来,所以j的方案数目包含在i中,那么num[i]=num[i]+num[j]。有了怎么转移,我们还要考虑一个严肃的问题,怎么去重??
看下面一段代码:
for(int i=2;i<=n;i++) for(int j=i-1;j>=1;j--){ if(f[i]==f[j]+1&&a[j]>a[i]) num[i]+=num[j]; if(a[i]==a[j]){ if(f[i]==1) num[i]=0; break; } }
这是什么意思呢??O(≧口≦)O
我们还是规定i>j,如果a[i]=a[j](因为我们是倒着往前找的)就代表我们不需要再往前枚举更新方案数目了,因为j之前的方案数目已经包含在j中了,而如果f[i]=1这代表什么呢??代表i前面没有比它大的数,那么显然f[j]也应该等于1,就是说ij方案数完全相同,这么来说如果我们保留i的方案数目,那么就会和j重复,而又因为i在j的后面所以我们显然是要保留j而把i的方案数目清零
代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=5000+5;
int n,a[maxn],f[maxn],num[maxn];
inline int read(){
char ch=getchar();
int f=1,x=0;
while(!(ch>='0'&&ch<='9')){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
x=x*10+ch-'0',ch=getchar();
return f*x;
}
signed main(void){
n=read();
for(int i=1;i<=n;i++)
a[i]=read(),f[i]=1,num[i]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
if(a[i]<a[j])
f[i]=max(f[i],f[j]+1);
for(int i=1;i<=n;i++)
if(f[i]==1)
num[i]=1;
for(int i=2;i<=n;i++) for(int j=i-1;j>=1;j--){ if(f[i]==f[j]+1&&a[j]>a[i]) num[i]+=num[j]; if(a[i]==a[j]){ if(f[i]==1) num[i]=0; break; } }
int mx=0,ans=0;
for(int i=1;i<=n;i++)
mx=max(mx,f[i]);
for(int i=1;i<=n;i++)
if(f[i]==mx)
ans+=num[i];
cout<<mx<<" "<<ans<<endl;
return 0;
}
by >o< neighthorn
相关文章推荐
- linux后台运行和关闭、查看后台任务
- java 反射的学习
- Linux基础知识的学习(二)
- 扩展欧几里德算法解线性方程ax+by=c [模板]
- 如何撰写一篇受人欢迎的博客
- SCU 4495 单词替换 KMP
- Linux head和tail命令
- Apache不重新编译,利用apxs工具给Apache添加模块,如cgi模块
- 微信红包(数组中出现次数超过一半的数字)----腾讯2016研发工程师编程题
- Python一键添加Zabbix监控脚本
- arcgsi属性表显示坐标
- NetRouter mt7620 openwrt MT7688 mqtt初探2
- Java并发编程:Callable、Future和FutureTask原理解析
- python点滴:判断字符串是否为合法json格式
- 2016.07.13【初中部 NOIP提高组 】模拟赛C
- 线性磁带文件系统(LTFS)
- Android Studio 如何使用AIDL
- java反射一些方法
- CSV文件excel打开乱码问题
- spoj LCS 【后缀自动机】