LuoGu 1108 低价购买 LIS方案数

一句话题意:两个序列的LIS的长度和方案数

首先这里n方的应该是要比nlog的好的,因为还涉及到一个求方案

主要考虑下第二问, 不同的方案数应该怎么求

实际上 对于一个长为len的子序列,

它的方案数即为所有长为len-1的,且可以转移到它的子序列 (都是满足题意的)的方案数之和

这样就比较好办了,直接在原本的求LIS的转移里搞搞就行了。

那么答案就是所有长度为LIS的方案数之和了。

但是还有一个问题,这样的话根本没考虑方案是否重复。

那么怎么样把相同的去掉呢??

我们把长度相等,当前对应位上的数也相等的,就先暂定为相等,删掉其中一个。

因为如果他们之前的也相同, 那么我们是可以直接全转移到当前的,删掉之前的。

如果之前的不相等, 那么之后它们的后面接上一个不同的数时,再作为两个判断就行了,互不影响。

贴下代码

#include<bits/stdc++.h>
using namespace std;
inline int gi()
{
    int x=0,w=0;char ch=0;
    while(!(ch>=‘0‘&&ch<=‘9‘))
    {
        if(ch==‘-‘) w=1;
        ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘)
    x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return w?-x:x;
}
int n,post[5001],tot[5001],maxn,times[5001];
long long ans;
int main()
{
    n=gi();
    for(int i=1;i<=n;i++) {
        post[i]=gi();
        tot[i]=1;
    }
    for(int i=1;i<=n;i++) {
        for(int j=1;j<i;j++)
            if(post[i]<post[j])
                tot[i]=max(tot[i],tot[j]+1);
        if(tot[i]>maxn) maxn=tot[i];
        for(int j=1;j<i;j++) {
            if(tot[i]==tot[j]&&post[i]==post[j]) times[j]=0;
            else
            if(tot[i]==tot[j]+1&&post[i]<post[j]) times[i]+=times[j];
        }
        if(!times[i]) times[i]=1;
    }
    for(int i=1;i<=n;i++)
        if(tot[i]==maxn) ans+=times[i];
    printf("%d %d",maxn,ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Bhllx/p/9807189.html

时间: 2024-10-16 12:57:36

LuoGu 1108 低价购买 LIS方案数的相关文章

洛谷P1108 低价购买[DP | LIS方案数]

题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买”的原则.写一个程序计算最大购买次数. 这里是某支股票的价格清单: 日期 1 2

1108 低价购买

难度:提高+/省选- 题目类型:动规 提交次数:3(待定) 涉及知识:线性动规 题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买

luogu P1108 低价购买

题目链接 luogu P1108 低价购买 题解 朴素n^2dp,对于方案的转移利用加法原理,dp每一种最有解的方案 代码 #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int maxn = 60007; int f[maxn],c[maxn],a[maxn]; int cnt=0; int n; int m

洛谷1108 低价购买

题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买”的原则.写一个程序计算最大购买次数.这里是某支股票的价格清单:日期  1  2

Luogu P1108 低价购买 DP

第一问求最长下降子序列,不提: 第二问:借鉴了最短路的方法??? 我们求出来了每个位置的最长下降子序列的长度,那么刻意这样这样转移 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> #inc

低价购买-最长下降子序列和方案计数

http://www.luogu.org/problem/show?pid=1108 题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低

低价购买 (动态规划,变种最长下降子序列(LIS))

题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(216范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买”的原则.写一个程序计算最大购买次数. 这里是某支股票的价格清单: 日期  1 

入门动态规划 洛谷P1108 低价购买

P1108 低价购买 题目描述 "低价购买"这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:"低价购买:再低价购买".每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循"低价购买:再低价购买"的原则

rqnoj 低价购买

题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买”的原则.写一个程序计算最大购买次数. 这里是某支股票的价格清单: 日期 1 2