POJ1952 BUY LOW, BUY LOWER DP

来源:互联网 发布:始祖鸟 户外装备 知乎 编辑:程序博客网 时间:2024/04/30 05:37

题意:

给一串数字,求最大的严格下降子序列,且还有求出这种序列的个数。

但是同时要注意重复序列只算一个。

比如 5 5 4 4 3,只有一种5 4 3.答案是3 1. 

思路:

对于严格单调子序列。算是很简单了吧。直接O(N^2)的复杂度实现即可。

至于找次数,其实本质也是DP,具体见代码。


#include<iostream>#include<algorithm>#define max(a,b) (a>b?a:b)#define min(a,b) (a<b?a:b)using namespace std;const int N=5005;int n;int seq[N];//int dp[N];//找最大长度int v[N];//找最大长度时的个数int main(){while(scanf("%d",&n)!=EOF){memset(seq,0,sizeof(seq));for(int i=1;i<=n;i++)scanf("%d",seq+i);memset(dp,0,sizeof(dp));memset(v,0,sizeof(v));v[0]=1;for(int i=1;i<=n;i++){int mx=0;for(int j=i-1;j>=1;j--){if(seq[i]<seq[j]){if(mx<dp[j]){mx=dp[j];v[i]=v[j];}else if(mx==dp[j]){v[i]+=v[j];//当dp值相等时,同时seq[i]!=seq[j],所以次数要相加。}}else if(seq[i]==seq[j])//当seq值相等时,排在前面的实际上已经无效了因为后面的肯定更优,所以v值置位0,因为序列相同时次数不叠加。{v[j]=0;}}dp[i]=mx+1;if(!mx)v[i]=1;}int ansa=0,ansb=0;for(int i=1;i<=n;i++){if(dp[i]>ansa){ansa=dp[i];ansb=v[i];}else if(dp[i]==ansa){ansb+=v[i];}}printf("%d %d\n",ansa,ansb);}return 0;}



原创粉丝点击