zoukankan      html  css  js  c++  java
  • 算法训练-Don't fear, DravDe is kind

    #include<bits/stdc++.h>
    using namespace std;
    int n,dp[100001],v[100001],c[100001],l[100001],r[100001],maxx=0,ok[100001],ll,num=0,m=0;
    vector<int> hash[100000];
    //方法:使用一维数组,dp[a]表示有a且以a为结尾的最大值,那么a的前后数目都确定了,
    //对于1<=k<a,判断l[k]+c[k]和l[a],来决定可不可以有k,同样r[k]!=c[a]+r[a];
    //初始值:对于l[a]==0的都可以作为第一个,则return v[a]
    //可以改用循环更快
    int DP(int a){
        if(l[a]==0) return v[a];
        if(dp[a]!=0) return dp[a];
        for(vector<int>::iterator i=hash[l[a]].begin();i!=hash[l[a]].end();i++){
            if(*i>=a||r[*i]!=c[a]+r[a]) continue;//因为用了hash,可能*i>=a,本来会循环到a-1的,不会出现这种情况
            if(DP(*i)+v[a]>dp[a]){
                dp[a]=DP(*i)+v[a];
                ok[a]=*i;//前驱数组
            }
        }
        if(dp[a]>maxx&&r[a]==0){//r[a]==0才更新最优解,平常不限制最后一个r[a]==0,否则无法循环。都是0;
            maxx=dp[a];
            ll=a;//最优值的位置
        }
        return dp[a];
    }
    void show(int k){
        if(k==-1) return;
        m+=v[k];
        show(ok[k]);
        cout<<k<<" ";
    }
    int main() {
        cin>>n;
        memset(dp,0,sizeof(dp));
        memset(ok,255,sizeof(ok));
        for(int i=1;i<=n;i++){
            cin>>v[i]>>c[i]>>l[i]>>r[i];
            hash[c[i]+l[i]].push_back(i);
        }
        for(int i=1;i<=n;i++) DP(i);
        //保证得到最优解,其实只需循环r[i]==0的点就行了,
        //但是事实上,后面的都会用到前面的,因为我是递归,所以直接递归后面反而会变慢
        int p=ll;
        while(ll!=-1){
            ll=ok[ll];
            num++;
        }
        cout<<num<<endl;
        show(p);
        cout<<endl;
        cout<<maxx<<endl;
        return 0;
    }
  • 相关阅读:
    设计模式---工厂模式和抽象工厂模式
    设计模式---简单工厂模式
    设计模式---设计模式的分类及六大原则
    分布式---Raft算法
    分布式---Paxos算法
    分布式---CAP和BASE理论
    分布式---分布式事务
    分布式---分布式锁
    css
    react生命周期
  • 原文地址:https://www.cnblogs.com/MorrowWind/p/13056330.html
Copyright © 2011-2022 走看看