zoukankan      html  css  js  c++  java
  • 题解 P1108 【低价购买】

    题目链接

    Solution 低价购买

    题目大意:求一个数列的最长下降子序列长度,以及长度最长的下降子序列的数量

    动态规划


    题目分析:求最长下降子序列是常规操作了,可以直接用朴素(O(n ^ 2))算法,也可以用二分做到(O(nlogn))复杂度,不过(n leq 5000)朴素算法随便跑

    那么如何统计方案呢?

    我们(dp)求最长下降子序列是设(d(i))表示以(i)结尾的下降子序列的最长长度.同理,我们可以用(f(i))表示以(i)结尾,长度为(d(i))的下降子序列的个数

    不难想到(f(i) = egin{cases} 1 qquad d(i) == 1 \ sum_{j}^{i - 1}{f(j);|;j < i ;;&&;;f(j) + 1 == f(i)} end{cases})

    但是这么做是有问题的,原因在于重复统计

    假如有(d(i) == d(j))并且(a(i) == a(j)),且满足$i <j (,有)f(i) leq f(j)$

    道理很简单,因为(f(i))的所有方案都被(f(j))所包括了,这时你需要将(f(j))置为(0),不然(f(j))的方案会被统计多次

    代码奉上,数据规模小就写的(O(n ^ 2))算法

    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 8192;
    int val[maxn],g[maxn],d[maxn],f[maxn],n,ans;//val为原数列,d[i]表示以i结尾的最长下降子序列长度,f[i]表示以i结尾,长度为d[i]的下降子序列的数量
    int main(){
    	ios::sync_with_stdio(false);
    	cin >> n;
    	for(int i = 1;i <= n;i++)
    		cin >> val[i];
    	for(int i = 1;i <= n;i++)
    		g[i] = -0x7fffffff;
    	ans = -1;
    	for(int i = 1;i <= n;i++){
    		int k = 0;
    		int l = 1,r = n;
    		while(l <= r){
    			int mid = (l + r) >> 1;
    			if(g[mid] > val[i])k = mid,l = mid + 1;
    			else r = mid - 1;
    		}
    		d[i] = k + 1;
    		g[k + 1] = val[i];
    		ans = max(ans,d[i]);
    	}
    	cout << ans << " ";//求LIS,没啥好说的
    	for(int i = 1;i <= n;i++){//依照转移方程
    		if(d[i] == 1)f[i] = 1;
    		for(int j = 1;j < i;j++)
    			if(d[i] == d[j] && val[i] == val[j])//如果j的方案已经被i包含了
    				f[j] = 0;
    			else if(d[i] == d[j] + 1 && val[i] < val[j])//统计方案
    				f[i] += f[j];
    	}
    	int sum = 0;
    	for(int i = 1;i <= n;i++){//输出答案
    		if(d[i] == ans)sum += f[i];
    	}
    	cout << sum << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    微信小程序scroll-viwe遇到的问题
    微信小程序缓存
    微信刷新数据不刷新页面的另一个方法
    微信小程序中无刷新修改
    Bayesian
    深度学习(七)object detection
    深度学习(十二)wide&deep model
    深度学习(十)训练时的调参技巧
    深度学习(九)过拟合和欠拟合
    深度学习(二)常见概念
  • 原文地址:https://www.cnblogs.com/colazcy/p/11514975.html
Copyright © 2011-2022 走看看