您的位置:首页 > 其它

POJ 1952 BUY LOW, BUY LOWER DP 最长下降序列求个数

2013-08-29 10:37 302 查看
注意:重复的只算一次

如何去掉一些重复的是本题的关键

我的去重思路:

7

5 3 7 6
3 2 1

6

5 3 7
3 1

5

5 3 2 1 3

第一组在推到 数字 2 的时候有 3会出现重复, 显然前面一个3是可有可无的。

第二组也一样,前面一个3是可有可无的。

1.如果最长下降序列中有后面一个3, 如第一二组数据,那么前面一个3是无用的,在推好后面一个3之后把之前的所用重复的计数数组清零

2.如果最长下降序列中只有前面一个3,如第三组数据, 做情况1的操作也是不会影响结果的,因为第三组的前面一个3的状态已经推到2后才被清零的。

#include<stdio.h>
#include<string.h>
bool vis[5003];
int a[5003], dp[5003], cnt[5003];
int main()
{
int i, j, k, max, n;
while( ~scanf("%d", &n))
{
int id = 0;
for(i = 1; i <= n; i++)
scanf("%d", &a[i]);
memset(dp, 0, sizeof(dp));
memset(cnt, 0, sizeof(cnt));
int max = 0;
for(i = 1; i <= n; i++)
{
//求长度
k = 0;
for(j = 1; j < i; j++)
if(a[i] < a[j] && dp[k] < dp[j])
k = j;
dp[i] = dp[k] + 1;
if(max < dp[i]) max = dp[i];

//求个数
if(dp[i] == 1) cnt[i] = 1;
else
{
for(j = 1; j < i; j++)
if(dp[j] + 1== dp[i] && a[i] < a[j])
cnt[i] += cnt[j];
}
for(j = 1; j < i; j++)
if(a[i] == a[j])
cnt[j] = 0;
}
int ans = 0;
for(i = 1; i <= n; i++)
if(max == dp[i]) ans += cnt[i];
printf("%d %d\n", max, ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: