P1108 低价购买dp

xiaoxiao2021-02-28  48

https://www.luogu.org/problem/show?pid=1108#sub

第一问,求一个最长的下降子序列就可以了。 难点在于第二问,解决方法: 设f[i]表示到i这一位置,最长下降子序列的最大方案数; 当构成序列相同时,可以看出……呃,举个例子吧: 股票价格为:4 , 2 , 2 , 3 , 1 最长的下降子序列为:4 2 1 或 4 2 1 或4 3 1 ,有两种是相同的,可以判断出数字2,用后面的就包括前面的了。 那么 , f[i]=Σf[j],( 0< j< i 且d[j]=d[i]-1且a[j]不重复) 处理时,就可以在处理出f[i]后,把前面的f[j]==f[i]的f[j]改为0就可以了。 !!而且,当且仅当d[i]=1时,f[i]=1!!切记!

代码

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int d[5009],f[5009]; int n,a[5009],m1,m2; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); d[i]=1; } d[n+1]=1;f[1]=1; for(int i=2;i<=n+1;i++) { int maxn=0; for(int j=1;j<=i-1;j++) { if(a[j]>a[i]&&d[j]>maxn) maxn=d[j]; } d[i]+=maxn; if(d[i]==1) f[i]=1; for(int j=1;j<=i-1;j++) { if(a[i]==a[j]) f[j]=0; if(d[j]==d[i]-1&&a[i]<a[j]) f[i]+=f[j]; } } printf("%d %d",d[n+1]-1,f[n+1]); return 0; }
转载请注明原文地址: https://www.6miu.com/read-55559.html

最新回复(0)