POJ 1952 BUY LOW, BUY LOWER
传送门:http://poj.org/problem?id=1952
题意:给你n个数,计算最长下降子序列的个数(并且不能重复)例如 5 3 5 3 该序列中 最长下降子序列的个数只有一个
思路:长度的话用进行转移复杂度
,关键是去重这一步如何计算。另外开一个
数组,表示以 i
为结尾的最长下降子序列的个数,然后在更新的时候,更新数组
,详细注释见代码块了
#include<iostream>
#include<cstdio>
using namespace std;
int num[5005];
int dp[5005];//dp代表以i结尾的最长下降子序列的长度
int f[5005];//f代表 以i为结尾的最长下降子序列的个数
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> num[i];
}
int ans = 0;
int cnt = 0;
for(int i = 0; i < n; i++)
{
dp[i] = 1;
for(int j = 0; j < i; j++)
{
if(num[i] < num[j])
{
dp[i] = max(dp[i], dp[j] + 1);
}
}
ans = max(dp[i], ans);
if(dp[i] == 1) //表示i点处只有num[i]一个元素 所有也只有这一个序列即是f[i]=1;
{
f[i] = 1;
}
for(int j = 0; j < i; j++)
{
if(num[i] == num[j]) // 进行去重了 表示只使用num[i]这个元素了 把其他相同的元素舍去了
f[j] = 0;
}
for(int j = 0; j < i; j++)
{
if(num[i] < num[j] && dp[i] == dp[j] + 1)
{
f[i] += f[j]; // 对以i为结尾的序列的个数 进行更新
}
}
}
cout << ans << " ";
for(int i = 0; i < n; i++)
{
if(ans == dp[i])
{
cnt += f[i];
}
}
cout << cnt << endl;
}