zoukankan      html  css  js  c++  java
  • [HG]Market 题解

    题目描述

    在比特镇一共有 (n) 家商店,编号依次为 (1)(n)
    每家商店只会卖一种物品,其中第 (i) 家商店的物品单价为 (c_i),价值为 (v_i),且该商店开张的时间为 (t_i)
    (Byteasar) 计划进行 (m) 次购物,其中第 (i) 次购物的时间为 (T_i),预算为 (M_i)
    每次购物的时候,(Byteasar) 会在每家商店购买最多一件物品,当然他也可以选择什么都不买
    如果购物的时间早于商店开张的时间, 那么显然他无法在这家商店进行购物。
    现在 (Byteasar) 想知道,对于每个计划,他最多能购入总价值多少的物品。请写一个程序,帮助 (Byteasar) 合理安排购物计划。
    注意:每次所花金额不得超过预算,预算也不一定要花完,同时预算不能留给其它计划使用。
    对于 (100\%) 的数据:
    (n, m in [1,300]; c_i,M_i in [1, 10^9]; vi,t_i,Ti in [1,300])
    观察数据发现不用开long long

    题解

    显然因为(c_i,M_i leq 10^9),不可能去做01背包。
    那么我们离线排序处理询问,并按照时间递增的顺序DP。
    每次对于一个物品,我们"倒做"01背包,即计算某个价值所需要的最小代价。

    分析

    考场一阵乱打,空间开小,(20)pts 滚粗。
    后来还莫名奇妙的多动规了一次,导致变为 (80)pts 。

    代码

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    struct Mark{
        int c, v, t;
        bool operator < (const Mark &rhs) const {
            return t < rhs.t;
        }
    } market[305];
    
    struct Qry{
        int t, m, id;
        bool operator < (const Qry &rhs) const {
            return t < rhs.t;
        }
    } qry[100005];
    
    int g[90005];
    int qans[100005];
    
    inline void flush(int u){
        for (int i = 90000; i >= market[u].c; --i){
            if (g[i] > g[i - market[u].c] + market[u].v)
                g[i] = g[i - market[u].c] + market[u].v;
        }
        for (int i = 90000; i >= 1; --i)
            if (g[i] > g[i + 1]) g[i] = g[i + 1];
    }
    
    int main(){
        int n, m; scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; ++i)
            scanf("%d %d %d", &market[i].v, &market[i].c, &market[i].t);
        sort(market + 1, market + n + 1);
        for (int i = 1; i <= m; ++i){
            int t, m; scanf("%d %d", &t, &m);
            qry[i] = {t, m, i};
        }
        sort(qry + 1, qry + m + 1);
        for (int i = 1; i <= 90004; ++i) g[i] = 1000000007;
        for (int i = 1, pos = 1; i <= m; ++i){
            for ( ; market[pos].t <= qry[i].t && pos <= n; ++pos)
                flush(pos);
            qans[qry[i].id] = upper_bound(g, g + 90001, qry[i].m) - g - 1;
        }
        for (int i = 1; i <= m; ++i)
            printf("%d
    ", qans[i]);
        return 0;
    }
    
  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/linzhengmin/p/11771410.html
Copyright © 2011-2022 走看看