zoukankan      html  css  js  c++  java
  • P1108 低价购买 DP

    P1108 低价购买 DP 

    题意:

      给定一个序列, 求最长下降子序列,及不重复的方案数。

      洛谷链接

    题解:

      最长下降子序列可以用 O(n^2) 的简单dp来求。  

      不难发现: 在一个元素互不相同的序列中,不会出现重复方案,因此可以通过dp累计答案(详见代码)。然后考虑去重,发现以x结尾的最长序列, 位置靠后的x的方案会包括位置靠前的x的方案。 因此可以删除最后一个x之前的x,dp后剩下的序列是互异的,因此答案不重复。

    代码:

      蒟丑

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <algorithm> 
    #define inf 0x3f3f3f3f
    using namespace std;
    
    struct p{
        int v=inf, l=0, a=0;
    }f[5005], lp;
    
    int n, ans=0, ans1=0;
    bool cmp(const p& a, const p& b){return a.l>b.l;}
    
    int main(){
        scanf("%d", &n);f[0].a=1;
        for(int i=1; i<=n; i++) scanf("%d", &f[i].v);
        
        for(int i=1; i<=n; i++){
            for(int j=0; j<i; j++){
                
                if(f[j].v == f[i].v) f[j].v = inf, f[j].l = -inf;
                else if(f[j].v < f[i].v || f[j].l < f[i].l-1) continue;
                else if(f[j].l == f[i].l-1) f[i].a += f[j].a;
                else f[i].l = f[j].l + 1, f[i].a = f[j].a; 
                
            } 
        }
        
        sort(f+1, f+n+1, cmp);
        int end = 2;while(f[end].l == f[end-1].l) end++;
    
        for(int i=1; i<end; i++) ans=f[i].l, ans1 += f[i].a;
        cout << ans << ' ' << ans1;
        
        return 0;
    }

       

  • 相关阅读:
    耶鲁大学——斯金纳理论基础
    耶鲁大学——弗洛伊德(基础)
    for input 'WID' 报错
    选中当前行wid
    微信支付
    vue.js列表渲染项目实例
    批量删除
    DIV 局部刷新
    DIV块刷新
    CMD DOS命令
  • 原文地址:https://www.cnblogs.com/ltdjcoder/p/13697644.html
Copyright © 2011-2022 走看看