zoukankan      html  css  js  c++  java
  • 线段树or优先队列+dp E. Lunar New Year and Red Envelopes

    线段树or优先队列+dp E. Lunar New Year and Red Envelopes

    题目大意:

    题解:

    (dp[i][j]) 表示到时间 (i) 打扰了 (j) 次获得的最少的硬币数量

    因为如果这个时间点有东西拿,那么必须按照策略拿,先预处理每一个时间点如果要拿的东西,然后写转移方程,这个转移有三种情况:

    • (dp[d[x]+1][j]=min(dp[d[x]+1][j],dp[i][j]))
    • 不拿,被打扰了 (dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]))
    • 如果没东西拿 (dp[i+1][j]=min(dp[i+1][j],dp[i][j]))

    预处理这个时间点要拿的东西,可以用线段树,也可以用优先队列。

    线段树就是一个区间更新,优先队列按照 (s) 排序放进去,然后队列里面第一关键词是w,然后是d,每次拿一个出来,如果当前时间点已经大于 (t) 了,那就删掉继续拿,一直到符合条件,或者队列为空。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 1e5+10;
    typedef long long ll;
    int num[maxn<<2],lazy[maxn<<2];
    int lc[maxn],rc[maxn],d[maxn],w[maxn];
    
    int Max(int x,int y){
        if((w[x]>w[y])||(w[x]==w[y]&&d[x]>d[y])) return x;
        return y;
    }
    void push_up(int id){
        num[id]=Max(num[id<<1],num[id<<1|1]);
    }
    
    void push_down(int id){
    	if(!lazy[id]) return ;
        num[id<<1]=Max(lazy[id],num[id<<1]);
        num[id<<1|1]=Max(lazy[id],num[id<<1|1]);
        lazy[id<<1]=Max(lazy[id<<1],lazy[id]);
        lazy[id<<1|1]=Max(lazy[id<<1|1],lazy[id]);
        lazy[id]=0;
    }
    void update(int id,int l,int r,int x,int y,int val){
        if(x<=l&&y>=r){
            num[id]=Max(num[id],val);
            lazy[id]=Max(lazy[id],val);
            return ;
        }
        push_down(id);
        int mid=(l+r)>>1;
        if(x<=mid) update(id<<1,l,mid,x,y,val);
        if(y>mid) update(id<<1|1,mid+1,r,x,y,val);
        push_up(id);
    }
    int query(int id,int l,int r,int pos){
        if(l==r) return num[id];
        push_down(id);
        int mid=(l+r)>>1;
        if(pos<=mid) return query(id<<1,l,mid,pos);
        return query(id<<1|1,mid+1,r,pos);
    }
    
    ll dp[maxn][220];
    int main(){
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=k;i++){
            scanf("%d%d%d%d",&lc[i],&rc[i],&d[i],&w[i]);
            update(1,1,n,lc[i],rc[i],i);
        }
        memset(dp,inf64,sizeof(dp));
        dp[1][0]=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=m;j++){
                if(dp[i][j]>=inf64) continue;
                int x = query(1,1,n,i);
    //            printf("i=%d j=%d x=%d
    ",i,j,x);
                if(!x) dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
                else{
                    if(j+1<=m) dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);
                    dp[d[x]+1][j]=min(dp[d[x]+1][j],dp[i][j]+w[x]);
    //                printf("dp[%d][%d]")
                }
            }
        }
        ll ans = inf64;
        for(int i=0;i<=m;i++) ans = min(ans,dp[n+1][i]);
        printf("%lld
    ",ans);
        return 0;
    }
    
    
    
  • 相关阅读:
    我用自己做的图书比价搜索买了一本书
    2.17
    最近的工作
    FireBug的Bug
    2.18
    tecent面试题解答
    .net杂记
    python的round测试
    最近在网上买书的体会
    关于迅雷评论的一个改造html css
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13396081.html
Copyright © 2011-2022 走看看