O(n^2) LIS 附带方案数

思路:

b [ i ] :以第i天为结尾,最大购买次数 

f [ i ] :到第i天,最大购买次数

ok [ a [ i ] ]:在与 a [ i ] 价格相同的情况下,该价格是否为最优 

y:当前 i ,循环到 j 时的最大 b [ ] 

转移方程:b [ i ] = max{b [ j ] }+1,1<=j<=i-1

              f [ i ]=f [ j ],b [ j ] > y

              f [ i ]+=f [ j ] ,b [ j ] == y && ! flag [ a [ i ] ]

 PS:1.flag [ ]需要以价格为下标以避免出现价格队列相同,而方案数累加的情况

      2.flag [ ]须定义为布尔数组,开2^16,大了或者开int会T,小了会WA

附代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 #define ll long long 
 5 const int N=5010;
 6 ll f[N],b[N],a[N],y;
 7 bool flag[65537];
 8 int main(){
 9     int n;
10     scanf("%d",&n);
11     for (int i=1;i<=n;i++)
12         scanf("%lld",&a[i]);
13     f[1]=b[1]=1;
14     a[0]=0;
15     for (int i=2;i<=n+1;i++){
16         y=0;
17         f[i]=1;
18         for (int j=i-1;j>=1;j--)
19             if (a[i]<a[j]){
20                 if (b[j]>y){
21                     memset(flag,0,sizeof(flag));
22                     flag[a[j]]=1;
23                     y=b[j];
24                     f[i]=f[j];
25                 }
26                 else if (b[j]==y&&!flag[a[j]]){
27                     f[i]+=f[j];
28                     flag[a[j]]=1;
29                 }
30             }
31         b[i]=y+1;
32     }
33     printf("%lld %lld",b[n+1]-1,f[n+1]);
34     return 0;
35 }
STD

 

posted on 2016-10-20 12:50  Absolutezero  阅读(214)  评论(0)    收藏  举报