zoukankan      html  css  js  c++  java
  • cf 1106e dp

    题意: 父亲在时间流水(n 1e5)上选择东西(k 1e5),每个有它的价值w和可被选择起止时间s,t,在选择之后以及到时间d,不可再选,父亲有固有的选择策略。

    但是女儿可以打断父亲m(200)次,使其不能选择,求最后的最小值是多少

    思路:dp  假设不存在打断的情况,那么父亲就按照一个固有的顺序选择了。d[i][j] 表示在打断i次 ,走到  j 可以获得最小值。

    按照时间的顺序, i可能打断那么就是 d[i+1[j+1]的时候,不打断,父亲按照固有策略去选择。

    值得学习的地方是,利用map的排序来 以及它的erase 和insert来表示了在时间i的选择的可能和最佳情况

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define all(v) v.begin(),v.end()
    #define mem(a) memset(a,0,sizeof(a))
    
    const int M = 202;
    const int N = 1e5+4;
    const ll mod =1e9+7;
    const ll INF = 1e18+4;
    const double eps = 1e-7;
    
    struct node{
        int d,w;
        //题目要求的父亲的选择策略
        friend bool operator <(node a,node b){
            return a.w>b.w || (a.w==b.w && a.d>b.d );
        }
    };
    
    map<node,int>choice;
    vector<node>V[N],T[N];
    node a[N];
    ll d[M][N];
    void insert(node x){
        if(choice.count(x))
            choice[x]++;
        else choice[x]=1;
    }
    
    void erase(node x){
        choice[x]--;
        if(choice[x]==0)
            choice.erase(x);
    }
    int main(){
        int n,m,k;
        cin>>n>>m>>k;
    
        for(int i=0;i<k;++i){
            int s,t,d,w;
            cin>>s>>t>>d>>w;
            V[s].pb(node{d,w});
            T[t+1].pb(node{d,w});
        }
    
        for(int i=1;i<=n;++i){
            for(int j=0;j<V[i].size();++j)
                insert(V[i][j]);
            for(int j=0;j<T[i].size();++j)
                erase(T[i][j]);
            //这是父亲要选择的最佳
            if(choice.size()){
                a[i]=  (*choice.begin()).first;
            }
            else a[i] =node{i,0};
        }
    
       for(int i=0;i<=m;++i)
            for(int j=0;j<=n+111;++j)
                d[i][j]=INF;
    
        ll ans =INF;
        d[0][1]=0;
        for(int j=0;j<=m;++j){
            for(int i=1;i<=n;++i){
                //假设在i时间打断
                d[j+1][i+1] = min(d[j+1][i+1],d[j][i]);
                //不打断,则父亲选择a[i] 之后的min是因为可能还有其他选择方法导致的可能
                d[j][a[i].d+1] = min(d[j][a[i].d+1],d[j][i]+a[i].w);
            }
            ans = min(ans,d[j][n+1]);
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    window.onload和DOMContentLoaded的区别
    存储
    JSONP的实现原理
    对于一个无线下拉加载图片的页面,如何给每个图片绑定事件
    事件冒泡
    通用的事件绑定函数
    拆解url的各部分
    如何检测浏览器的类型
    DOM节点操作
    es6基本用法
  • 原文地址:https://www.cnblogs.com/wjhstudy/p/10350414.html
Copyright © 2011-2022 走看看