zoukankan      html  css  js  c++  java
  • cf1106E 线性dp+multiset

    之前看错题目了,以为父亲的选择时按最大收益来的。结果并不是

    /*
    注意题目中说只要某个时间父亲可以取得红包,他就取硬币数最多同时耗时最小的那个
    就是不管后续如何,不一定满足最大收益
    dp[i][j]表示时间i被干扰j次所得的最小收益
    dp[i][j]=dp[a+1][j]+b; <a,b>是时间i可取的价值最大同时耗时最小的红包,这是必定取的
    dp[i][j]=min(dp[i][j],dp[i+1][j-1])决定是否进行干扰
    由状态转移方程可以看出,前面时间的状态是由后面时间的状态取得的,所以外层i循环从后往前
    */

    #include<bits/stdc++.h>
    #include<set>
    #include<vector>
    using namespace std;
    #define maxn 100005
    #define ll long long 
    ll dp[maxn][205],n,m,k;
    vector<pair<ll,ll> >S[maxn],E[maxn];
    multiset<pair<ll,ll> >s;//默认是从小到大排序的,由于要取出的是价值最大的元素,所以在存入时把w存为-w 
    
    int main(){
        cin>>n>>m>>k;
        for(int i=1;i<=k;i++){
            ll s,t,d,w;
            cin>>s>>t>>d>>w;
            S[s].push_back(make_pair(-w,-d));
            E[t].push_back(make_pair(-w,-d));
        }
        
        memset(dp,0,sizeof dp);
        for(int i=n;i>=1;i--){
            for(int j=0;j<E[i].size();j++)s.insert(E[i][j]);
            pair<ll,ll> t=make_pair(0,0);
            ll a,b;
            if(!s.empty()){
                t=*s.begin();
                b=-t.first;a=-t.second+1;
            }
            else  a=i+1,b=0;
            for(int j=0;j<=m;j++){
                dp[i][j]=dp[a][j]+b;//未被干扰的决策 
                if(j)dp[i][j]=min(dp[i][j],dp[i+1][j-1]); 
            }
            for(int j=0;j<S[i].size();j++)s.erase(s.find(S[i][j]));
        } 
        printf("%lld
    ",dp[1][m]);
    } 
  • 相关阅读:
    第三次作业
    第二次作业
    第一次作业
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    随笔
    第五次作业
    第四次作业
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10345661.html
Copyright © 2011-2022 走看看