POJ 1952 BUY LOW, BUY LOWER
来源:互联网 发布:三菱伺服调试软件 编辑:程序博客网 时间:2024/04/30 06:43
来源:http://poj.org/problem?id=1952
题意:求最长单调递减子序列的长度以及有多少种途径到达该最长单调递减子序列。
思路:求最长单调递减子序列是比较容易的了,关键是求路径的条数。而且还要去重。如5 5 2 2 1,其实是只有一条5 2 1。该题难点就在于去重,去重方法如下:
我们在求单调递减子序列的时候,可以用一个二重for循环求,在循环中dp[i]表示的是到第i个数时的单调递减子序列的最长长度,我们用如下的for循环求递减子序列的长度:
for(int j = 0;j < i;++j){ if(num[i] < num[j]){ if(dp[j] > mmax)mmax = dp[j]; } }我们设数组cnt[i]表示有几种途径到达第i个数字时的最长长度。则cnt[i]的取值决定于cnt[j](num[j] > num[i] 且 dp[j] == dp[i] - 1 且 j < i),由于要去重,所以需要倒着循环,这是个比较难想的地方。我就在这里卡了一天。。。。可以用下面的代码实现:
CLR(flag,false); for(int j = i-1;j >= 0 ;--j){ if(num[i] < num[j] ){ if(dp[j] == mmax && !flag[num[j]]){flag[num[j]] = true;cnt[i] += cnt[j];} } }其中的flag数组就是去重的功能,即如果是两个相同的数都能到达num[i],则计算一个就可以,且从后计算。
附几组数据:
5
20 18 25 18 17
输出:3 2
4
20 15 10 10
输出:3 1
9
100 96 30 200 196 30 300 296 30
输出:3 3
5
5 5 2 2 1
输出:3 1
这几种情况如果都考虑了的话,基本就对了。
代码:
#include <iostream>#include <string.h>#include<cstdio>using namespace std;#define CLR(arr,val) memset(arr,val,sizeof(arr))const int N = 5010;int dp[N],num[N],sum[N];bool flag[10*N];long long cnt[N];int main(){//freopen("1.txt","r",stdin);int n;while(scanf("%d",&n) != EOF){ for(int i = 0;i < n;++i) scanf("%d",&num[i]); CLR(dp,0); CLR(cnt,0); CLR(flag,false); dp[0] = 1;cnt[0]=1; int mmax = 0; for(int i = 1;i < n;++i){ mmax = 0; for(int j = 0;j < i;++j){ if(num[i] < num[j]){ if(dp[j] > mmax)mmax = dp[j]; } } CLR(flag,false); for(int j = i-1;j >= 0 ;--j){ if(num[i] < num[j] ){ if(dp[j] == mmax && !flag[num[j]]){flag[num[j]] = true;cnt[i] += cnt[j];} } } if(cnt[i] == 0)cnt[i] = 1; dp[i] = mmax+1; } mmax = 0; for(int i = 0;i < n;++i){ if(mmax < dp[i])mmax = dp[i]; } long long ans = 0; CLR(flag,false); for(int i = n-1;i >= 0;--i){ if(dp[i] == mmax) {if(!flag[num[i]]){ ans += cnt[i]; flag[num[i]] = true;}} } printf("%d %lld\n",mmax,ans);}return 0;}
话说这道题卡了一天多啊,,10417832ac_Bool1952Wrong Answer C++739B2012-07-10 19:30:3710429494ac_Bool1952Accepted296K125MSC++1215B2012-07-12 08:53:09wa了8次。。。。
- POJ 1952 BUY LOW, BUY LOWER(DP)
- POJ 1952 BUY LOW, BUY LOWER
- poj 1952 BUY LOW, BUY LOWER
- POJ 1952 buy low,buy lower
- poj 1952 buy low buy lower(DP)
- poj 1952 Buy low, buy lower
- POJ 1952 BUY LOW, BUY LOWER
- POJ 1952 BUY LOW, BUY LOWER
- POJ 1952 BUY LOW, BUY LOWER
- poj 1952 BUY LOW, BUY LOWER dp
- POJ 1952 BUY LOW, BUY LOWER
- poj 1952buy low, buy lower
- POJ 1952 BUY LOW, BUY LOWER DP
- POJ 1952 Buy Low,Buy Lower
- POJ 1952 BUY LOW, BUY LOWER
- POJ 1952BUY LOW, BUY LOWER
- POJ 1952 BUY LOW, BUY LOWER
- POJ 1952 C++:BUY LOW, BUY LOWER
- VB:主窗口关闭,进程不一定关闭
- Delphi与XML
- cuuby,使用文件流输出图片时,action重复执行的问题
- c++学习7之关联容器
- 如何开启SUSE Linux的SSH
- POJ 1952 BUY LOW, BUY LOWER
- stm--调试端口 和 普通 IO口
- JAVA异常处理(2)
- 墨菲定律
- static的详细讲解
- 中文分词与马尔科夫模型之二(隐马尔科夫模型与维特比)
- 【郭林专刊】MVC已过时,MOVE时代来临?
- C语言深度剖析--结构体
- FLV视频封装格式详解