zoukankan      html  css  js  c++  java
  • CF-629 D

    • 求上升子序列的最大和。O(n^2)会暴力,在查询的时候要用线段树维护
    • 因为权值是浮点数,故先离散化一下,设第 i 个位置的权值,从小到大排名为 id。那么dp转移中 $$d[i] = max(d[i],d[i] + d[j])$$ 其中$$j<i & id[j]<id[i]$$ 故线段树结点区间[l,r]维护的是id = l 到 id = j 中的最大 dp值
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 100000;
    double vol[N],r,h;
    int n,has[N],g[N],dp[N],tot;
    int c[N];
    vector<double> v;
    int getId(double a){
        return lower_bound(v.begin(),v.end(),a)-v.begin()+1;
    }
    struct Tree{
        int l,r;
        double data;
    }t[4*N];
    void build(int p,int l,int r){
        t[p].l = l;
        t[p].r = r;
        if(l==r){
            t[p].data = 0;return;
        }
        int mid = l+r>>1;
        build(p*2,l,mid);
        build(p*2+1,mid+1,r);
        t[p].data = 0;
    }
    void change(int p,int x,double val){
        if(t[p].l == t[p].r && t[p].l == x){
            t[p].data = max(t[p].data,val);
            return ;
        }
        int mid = (t[p].l+t[p].r)>>1;
        if(x<=mid)change(p*2,x,val);
        else change(p*2+1,x,val);
        t[p].data = max(t[p*2].data,t[p*2+1].data);
    }
    double ask(int p,int l,int r){
        if(t[p].l>=l&&t[p].r<=r)return t[p].data;
        int mid = (t[p].l+t[p].r)>>1;
        double val = 0;
        if(l<=mid)val = max(val,ask(p*2,l,r));
        if(r>mid)val = max(val,ask(p*2+1,l,r));
        return val;
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&r,&h);
            vol[i] = acos(-1) * r * r * h;
            v.push_back(vol[i]);
        }
        sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
        build(1,1,n);
        double res = 0;
        for(int i=1;i<=n;i++){
            int id = getId(vol[i]);
            double now = ask(1,1,id-1);
            now = max(vol[i],vol[i]+now);
            res = max(res,now);
            change(1,id,now);
        }
        printf("%.10lf
    ",res);
        return 0;
    }
    
    • 辗转了很多次,惭愧,线段树做的题太少了

    法二:离散化+树状数组

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    const int inf = 0x3f3f3f3f;
    double vol[N],c[N];
    vector<double> v;
    int n,g[N];
    int getId(double res){
        return lower_bound(v.begin(),v.end(),res) - v.begin() + 1;
    }
    void add(int x,double y){
        c[x] = y;
        for(;x<=n;x+=x&-x)c[x] = max(c[x],y);
    }
    double ask(int x){
        double res = 0;
        for(;x;x-=x&-x)res = max(res,c[x]);
        return res;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            double r,h;
            scanf("%lf%lf",&r,&h);
            double vo = acos(-1) * r * r * h;
            vol[i] = vo;
            v.push_back(vo);
        }
        sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
        double res = 0;
        for(int i=1;i<=n;i++){
            int x = getId(vol[i]);
            double now = ask(x-1) + vol[i];
            add(x,now);
            res = max(res,now);
        }
        printf("%.10lf
    ",res);
        return 0;
    }
    

  • 相关阅读:
    Flux 是什么?
    看深度学习框架排名第一的TensorFlow如何进行时序预测!
    时间序列ARIMA模型预测方法,及相关函数使用方法介绍
    解决MATLAB在K-means提示“KMEANS does not accept complex data.”错误
    机器学习——朴素贝叶斯分类器
    K-近邻分类法及tabulate、rng、categorical、varfun、discretize函数用法介绍
    灰色预测模型及MATLAB实例
    数学建模——预测模型简介
    支持向量机(SVM)MATLAB 实例讲解,及选择训练方式使误差率尽可能减为0
    批量修改文件后缀名,文件批量排序
  • 原文地址:https://www.cnblogs.com/1625--H/p/10661079.html
Copyright © 2011-2022 走看看