码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu P1108 低价购买 DP

时间:2019-04-28 12:41:48      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:sdi   ns2   lld   sig   char   nbsp   +=   main   tchar   

第一问求最长下降子序列,不提;

第二问:借鉴了最短路的方法???

我们求出来了每个位置的最长下降子序列的长度,那么刻意这样这样转移

if f[i]==f[j]+1&&a[i]<a[j](i>j) 这代表f[i]可以由f[j]转移过来,所以 f[i]+=f[j]

但是会重复,所以当f[i]==f[j]&&a[i]==a[j]  时,说明没有发生任何转移,去掉一个。

初值 当f[i]==1时,c[i]=1;

#include<iostream>
#include<cstdio>
#include<algorithm>
#define max(a,b) a>b?a:b
#define R register int 
using namespace std;
const int N=5010;
int n;
int a[N],f[N],c[N];
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==-?-1:fix;
    do ret=(ret<<3)+(ret<<1)+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
signed main() {
    n=g();for(R i=1;i<=n;i++) a[i]=g();
    long long ans1=0,ans2=0;
    for(R i=1;i<=n;i++) {
        f[i]=1; 
        for(R j=1;j<i;j++) if(a[i]<a[j]) f[i]=max(f[i],f[j]+1);
        ans1=max(ans1,f[i]);
    }
    for(R i=1;i<=n;i++) {
        if(f[i]==1) c[i]=1;
        for(R j=1;j<i;j++) 
            if(f[i]==f[j]+1&&a[i]<a[j]) c[i]+=c[j];
            else if(f[i]==f[j]&&a[i]==a[j]) c[i]=0;
        if(f[i]==ans1) ans2+=c[i];
    }
    printf("%lld %lld\n",ans1,ans2);
}

2019.04.28

Luogu P1108 低价购买 DP

标签:sdi   ns2   lld   sig   char   nbsp   +=   main   tchar   

原文地址:https://www.cnblogs.com/Jackpei/p/10783140.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!