P1108 低价购买

题意:给出n个数,求最长下降子序列,求不同最长下降子序列的方案数

      相同方案的定义为:长度相同并且有元素相同  比如这样一个序列 9 7 6 5 5   

         (9 7 6 5) (9 7 6 5)  这两个5的下标分别为4 5 ,但是这样的序列是相同的

思路:首先我们求出最长下降子长度

     在求出前i个数的最长下降子序列长度后

        我们就开始遍历求方案数

          那么如何求方案数呢?

            当满足 dpx[j]+1==dpx[i]&&a[j]>a[i] 时,即可dpy[i]+=dpy[j];

              但是这样做后,还会剩下重复的方案

                假如出现 a[j]==a[i]&&dpx[i]==dpx[j]   时,dpy[j]=0;即可

                  最后通过更新出来的最长序列长度来枚举一遍,在此长度下的方案数即可

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=5e3+10;
 4 int dpx[maxn];
 5 int dpy[maxn];
 6 int a[maxn];
 7 int main()
 8 {
 9     int n;
10     scanf("%d",&n);
11     for(int i=1;i<=n;i++)
12         scanf("%d",&a[i]);
13     int mx=1;
14     for(int i=1;i<=n;i++){
15         for(int j=i-1;j>=1;j--){
16             if(a[j]>a[i])
17                 dpx[i]=max(dpx[i],dpx[j]+1);
18         }
19         if(!dpx[i]) dpx[i]=1;
20         for(int j=1;j<i;j++){
21             if(a[j]==a[i]&&dpx[i]==dpx[j])
22                 dpy[j]=0;
23             else if(dpx[j]+1==dpx[i]&&a[j]>a[i])
24                 dpy[i]+=dpy[j];
25         }
26         if(!dpy[i]) dpy[i]=1;
27         mx=max(mx,dpx[i]);
28     }
29     int ans=0;
30     for(int i=1;i<=n;i++)
31         if(dpx[i]==mx)
32             ans+=dpy[i];
33     printf("%d %d\n",mx,ans);
34     return 0;
35 }
View Code

 

         

posted @ 2020-03-24 20:09  古比  阅读(82)  评论(0编辑  收藏  举报