poj 1952 最长递减子序列+求个数
来源:互联网 发布:mac怎么启用flash 编辑:程序博客网 时间:2024/06/06 01:20
题意:给出N个数的序列,求最长递减子序列,并且求出不同的序列方案个数。
解释:如 4 3 2 4 3 2这个序列,最长递减子序列长度显然为3,但是个数只计算一次,因为前后两个都是4 3 2,看做是相同的。
思路:计数搞不定,看的别人题解。num[i]表示前i个数的序列中,达到最长递减(以s[i]为最后一位)的而且该序列方案中前一个数在s[j]之后的方案个数。其中s[j]为最靠右的=s[i]的数字。这样便把重复的分来计数了。
#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <queue>using namespace std;#define INF 0x3fffffff#define clr(s,t) memset(s,t,sizeof(s))#define N 5005int s[N],num[N],dp[N],n;int main(){ int i,j,sum=0,res = 0; scanf("%d",&n); for(i = 1;i<=n;i++){ scanf("%d",&s[i]); dp[i] = num[i] = 1; } for(i = 2;i<=n;i++){ for(j = i-1;j>=1;j--){ if(s[j] > s[i]){ if(dp[j] >= dp[i]){ dp[i] = dp[j]+1; num[i] = num[j]; }else if(dp[j]+1 == dp[i]){ num[i] += num[j]; } }else if(s[j]==s[i]){ if(dp[i] == 1) num[i] = 0; break; } } } for(i = n;i>=1;i--) res = max(res,dp[i]); for(i = n;i>=1;i--) if(dp[i] == res) sum += num[i]; printf("%d %d\n",res,sum); return 0;}
0 0
- poj 1952 最长递减子序列+求个数
- poj 1952 最长递减子序列个数
- 求最长递减子序列
- 求最长单调递减子序列
- 求最长单调递减子序列
- 求最长递减子序列LCS
- 求最长单调递减子序列
- 求最长递减子序列(转载)
- 求最长单调递减子序列
- 求最长单调递减子序列
- 求数组的最长递减子序列
- 最长递减子序列
- 最长递减子序列
- 最长递减子序列
- 最长递减子序列
- 最长递减子序列
- POJ 1552 BUY LOW, BUY LOWER(最长单调递减子序列求方案数)
- poj 1952 BUY LOW, BUY LOWER (最长递减子序列+不同子序列计数)
- ESP8266-01细玩笔记(二)
- Ad-hoc网络
- HashMap实现原理分析
- ocp-36
- hdu 3336 Count the string(★)
- poj 1952 最长递减子序列+求个数
- 获取当前jvm下的所有线程
- 读懂diff
- JAVA设计模式之单件模式
- hdoj 2855 Fibonacci Check-up 【打表找规律 + 矩阵快速幂】
- Word Search II
- jasperReport生成html图片显示问题
- 把不是镂空图的图片 转化成 镂空图
- ios申请真机调试( xcode 5)详细解析