zoukankan      html  css  js  c++  java
  • F. Programming Contest

    Programming Contest

    题目链接:F - Programming Contest (atcoder.jp)

    题目大意

    ​用T分钟的时间去解决N道题,每道题需要相应的时间。可以选择其中的任意道,使剩下的时间最少。

    解题思路

    ​最容易想到的就是递归遍历所有的可能,然后取满足条件的最大值。然而N最大为40,每个题都有选和不选两种情况,这样最大时间复杂度为(O(2^{40})),肯定超时。

    ​所以我们得采用trick优化。

    ​我们将n个数两等分,然后分别枚举两部分的所有情况,并将结果保存在数组中,这样最大时间复杂度为(O(2*2^{20}))。然后我们再将得到的两个数组v1,v2升序排序,从v1和v2中各取一个数,求组成的最大的不超过T的数就行。对v1中的每一个数,我们可以直接二分v2寻找最佳匹配,此过程最大时间复杂度为(O(2^{20}log2^{20}))

    Code

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    typedef long long ll;
    int n, t, a[44];
    vector<ll> v1, v2;
    ll ans;
    
    
    void dfs(int i, int e, ll sum, vector<ll>& v){
        if(i==e){
            if(sum<=t) {
                ans = max(ans, sum);
                v.push_back(sum);
            }
            return;
        }
        dfs(i+1, e, sum, v);
        if(sum+a[i] <= t) dfs(i+1, e, sum+a[i], v);
    }
    
    int main(void)
    {
        cin>>n>>t;
        for(int i=0;i<n;++i) cin>>a[i];
        dfs(0, n/2, 0, v1);
        dfs(n/2, n, 0, v2);
        sort(v1.begin(), v1.end());
        sort(v2.begin(), v2.end());
        int num1 = v1.size();
        for(int i=0;i<num1;++i){
            int p = upper_bound(v2.begin(), v2.end(), t-v1[i]) - v2.begin();
            ans = max(ans, v1[i]+v2[p-1]);
        }
        cout<<ans;
        return 0;
    }
    
    海到无边天作岸,山登绝顶我为峰
  • 相关阅读:
    Linux date自己实现代码
    Linux常用指令
    awk getline命令
    文档资料记录
    数学之美番外篇:平凡而又神奇的贝叶斯方法
    最小二乘法(ZZ)
    SpringMVC简单使用教程
    Oracle设置序列方法
    Bootstrap Table的使用详解
    Html中div块居中显示
  • 原文地址:https://www.cnblogs.com/Fiona0726/p/14026628.html
Copyright © 2011-2022 走看看