zoukankan      html  css  js  c++  java
  • 牛客寒假6-B重排列| dp计数

    题目地址:https://ac.nowcoder.com/acm/contest/3007/D

    思路

    1.无后效性:假设前i-1个位置已经找好,那么前i-1个位置的值就不再影响后面了
    2.那么我们考虑第i个位置的方案,只需要找a数组中后面比b[i]大的个数就是当前第i个位置能放的种类数。
    找方案数,用乘法原理。
    状态转移方程:dp[i] = dp[i-1] * a数组中i~n中比b[i]大的数的个数

    3.然后进行优化:
    a数组中i~n中比b[i]大的数的个数,
    可以用二分查找O(nlogn)在a数组中查找比b[i]大的个数,
    也可以用双指针,因为先对a数组排序,查找比b[i]大的个数时,肯定是从已经找到比b[i-1]大的的指针j向后移动了。

    4.边界
    dp[0] = 1;

    AC代码

    方法一:dp + 双指针
    时间复杂度O(2n)

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int maxn = 1e5+10;
    const ll mod = 1e9+7;
    
    ll a[maxn],b[maxn];
    ll dp[maxn];
    int n;
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	for(int i=1;i<=n;i++) cin>>b[i];
    	sort(a+1,a+1+n);
    	sort(b+1,b+1+n);
    	int j = 0;
    	dp[0] = 1;
    	//O(2n)
    	for(int i=1;i<=n;i++){
    		while(j < n && a[j+1] <= b[i]) j++;
    		dp[i] = dp[i-1] * max(0,j-i+1) % mod;
    	}
    	cout<<(dp[n]+mod)%mod;
    	return 0;
    }
    

    方法二:dp + 二分
    时间复杂度O(nlogn)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod = 1e9+7;
    const int maxn = 1e5+10;
    int n;
    ll a[maxn],b[maxn],dp[maxn];
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	for(int i=1;i<=n;i++) cin>>b[i];
    	sort(a+1,a+n+1);
    	sort(b+1,b+n+1);
    	dp[0] = 1; 
    	//O(nlogn)
    	for(int i=1;i<=n;i++){
    		int r = upper_bound(a+1+i-1,a+n+1,b[i]) - a - 1; //二分查找比b[i]大的 
    		if(r > n) r = 0; //没查找到r会>n 此时令r = 0 说明不合法 
    		dp[i] = (dp[i-1] * max(0,r-i+1)) % mod;
    	}
    	cout<<(dp[n]+mod)%mod;
    	return 0;
    }
    
    /*
    4
    1 1 2 3
    1 2 3 4
    */
    
  • 相关阅读:
    P5318 【深基18.例3】查找文献 —— 图的两种遍历
    电子合同有效性需要解决的问题
    软件测试流程
    浅析HTTP与HTTPS的区别
    输入URL到网页显示的全过程
    TCP协议详细讲解
    Git操作
    robot framework环境搭建及注意事项
    测试面试问题总汇
    python之random模块详解
  • 原文地址:https://www.cnblogs.com/fisherss/p/12316646.html
Copyright © 2011-2022 走看看