• 【POJ1952】逢低吸纳 dp+计数


    题目大意:给定一个有 N 个数的序列,求其最长下降子序列的长度,并求出有多少种不同的最长下降子序列。(子序列各项数值相同视为同一种)

    update at 2019.4.3
    题解:求最长下降子序列本身并不难,是一道非常经典的线性dp问题,关键在于dp计数部分。这道题跟一般的状态转移计数不同,这里并不是按照状态去计数,对于状态来说不会有重复的情况发生。
    考虑何时会产生答案重叠。对于序列中两个值相同的元素 (a_i,a_j,(j<i)),到 i 之前的序列被这两个相同的元素分成了两部分,即:小于 j 的序列(第一部分)和大于 j 小于 i 的序列(第二部分)。下面分情况进行讨论。

    1. 第二部分对 dp[i] 没有产生任何贡献,即:第二部分的元素值都小于 a[i],此时发现 a[i] 和 a[j] 完全等价,因此 i 的答案贡献应该为 0。
    2. 第二部分对 dp[i] 产生了贡献,且 dp[i]>dp[j],这时 i 和 j 的序列显然不会有重叠的概念,毕竟都不一样长嘛qwq。
    3. 第二部分对 dp[i] 产生了贡献,且 dp[i]=dp[j],比如序列 1 3 4 2 4,这时,对于第一个 4 之前的答案种数对 i 忽略不计即可,不过第二部分对 i 的种数贡献需要计入 f[i]。

    代码如下

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define all(x) x.begin(),x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> P;
    const int dx[]={0,1,0,-1};
    const int dy[]={1,0,-1,0};
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const int maxn=5010; 
    const double eps=1e-6;
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll sqr(ll x){return x*x;}
    inline ll read(){
    	ll x=0,f=1;char ch;
    	do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
    	do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
    	return f*x;
    }
    /*--------------------------------------------------------*/
    
    int n,a[maxn];
    int dp[maxn],f[maxn],ans1,ans2;
    
    void read_and_parse(){
    	n=read();
    	for(int i=1;i<=n;i++)a[i]=read();
    }
    
    void solve(){
    	for(int i=1;i<=n;i++){
    		dp[i]=1;
    		for(int j=1;j<i;j++)if(a[j]>a[i])dp[i]=max(dp[i],dp[j]+1);
    		ans1=max(ans1,dp[i]);
    	}
    	for(int i=1;i<=n;i++){
    		if(dp[i]==1)f[i]=1;
    		for(int j=1;j<i;j++)
    			if(a[j]>a[i]&&dp[i]==dp[j]+1)f[i]+=f[j];
    			else if(a[i]==a[j]&&dp[i]==dp[j])f[i]=0;
    		if(dp[i]==ans1)ans2+=f[i];
    	}
    	printf("%d %d
    ",ans1,ans2);
    }
    
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
    
  • 相关阅读:
    Linux 期中架构 PHP
    Linux 期中架构 MySQL
    Python 示例 饮水记录
    Linux 期中架构 inotify
    Linux期中架构 全网备份案例
    分布式存储系统Ceph部署过程 · Jayden's Blog
    Go语言汇编器的设计
    linux基础3
    6.2.2 多余的列另起一行
    linux网络设备驱动2
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/9965360.html
Copyright © 2020-2023  润新知