zoukankan      html  css  js  c++  java
  • 【洛谷P1108】低价购买

    低价购买

    题目链接

    n<=5000 n^2的算法是可以接受的

    第一个数字显然是求最长下降子序列,可以n^2或nlognDP

    要求方案数,可以在n^2算法中做一些修改,DP求方案数

    dp[i]表示以第i个数为结尾的最长下降子序列

    f[i]表示以第i个数为结尾的最长下降子序列的个数

    当a[j]<a[i]且dp[i]==dp[j]+1时,f[i]可以由f[j]转移 f[i]+=f[j]

    而当a[i]==a[j]且dp[i]==dp[j]时,构成的子序列视为相同的,所以将一个置为0,防止重复计算

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 #define N 5010
     6 int n,a[N],dp[N],f[N],ans1,ans2;
     7 inline int read(){
     8     int x=0; char c=getchar();
     9     while(c<'0'||c>'9') c=getchar();
    10     while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
    11     return x;
    12 }
    13 int main()
    14 {
    15     n=read();
    16     for(int i=1;i<=n;i++)
    17      a[i]=read();
    18     for(int i=1;i<=n;i++){
    19         for(int j=1;j<i;j++)
    20          if(a[i]<a[j]&&dp[i]<dp[j])
    21           dp[i]=dp[j];
    22         dp[i]++;
    23         for(int j=1;j<i;j++)
    24          if(dp[i]==dp[j]&&a[i]==a[j])
    25           f[j]=0;
    26          else if(a[i]<a[j]&&dp[i]==dp[j]+1)
    27           f[i]+=f[j];
    28         if(!f[i]) f[i]=1;
    29     }
    30     for(int i=1;i<=n;i++)
    31      ans1=max(ans1,dp[i]);
    32     for(int i=1;i<=n;i++)
    33      if(dp[i]==ans1) ans2+=f[i];
    34     printf("%d %d
    ",ans1,ans2);
    35     return 0;
    36 }
  • 相关阅读:
    创建目录(单个目录和多级子目录)方法
    C++中创建目录
    C/C++中判断某一文件或目录是否存在
    Eclipse快捷键大全(转载)
    关于注册模型失败的分析
    框架Model注册失败
    nop中导航属性的写法
    CodeFirst中导航属性的代码实现 理解
    MVC下验证码
    Androidi学习笔记 1
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/9360967.html
Copyright © 2011-2022 走看看