poj 动态规划DP - 1664 BUY LOW, BUY LOWER

最大下降子序列,变相的最大上升子序列题目。主要是多了一个判断最大序列的个数。一般递推式是dp[x] = max(dp[x],dp[y]+1),这里多了一个count用来计算序列个数。

在内部循环剩下的序列时,我们从尾向头部循环,因为显然,目前最大的下降子序列一般在后面,这样的话,我们能迅速找到最大子序列,并且往前找与这个序列长度相同的结点,计算序列个数。

# include<stdio.h>
#include<stdlib.h>
# include<string.h>
#define MAX 5002
struct dps{
	int num;
	int count;
};
#define max(x,y)(x>y?x:y)
int price[MAX];
dps dp[MAX];

int cmp(const void*a,const void*b)
{
	return (*(dps*)b).num > (*(dps*)a).num?1:-1;
}
int main(){
	int n,i,j,time,num;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&price[i]);
		dp[i].num=1;dp[i].count=1;
	}
	for(i=2;i<=n;i++){
		for(j=i-1;j>=0;j--){
			if(price[i]<price[j]){
					if(dp[j].num+1 > dp[i].num){
						dp[i].num = dp[j].num+1;
						dp[i].count = dp[j].count;
                    }
                    else if (dp[j].num + 1 == dp[i].num)
                            dp[i].count += dp[j].count;

			}
			else if(price[i] == price[j]){
                        if (dp[i].num== 1)
							dp[i].count = 0;
                        break;
                    }
		}
	}

	qsort(dp,MAX,sizeof(dps),cmp);
	i=0;num=dp[0].num;time=0;
	while(dp[i].num==num){ 
			time+=dp[i].count;
			i++;
	}
	printf("%d %d\n",num,time);
	return 0;
}


你可能感兴趣的:(动态规划,poj)