zoukankan      html  css  js  c++  java
  • CF500F New Year Shopping

    题面

    题解

    给个不要脑子的做法。

    因为这道题是物品会存在一段时间,对每个时间点求出 (0/1) 背包的值。然后 (n) 和背包大小都是 (4000) 级别,于是考虑线段树分治。

    也就是将所有物品丢到线段树上去,dfs 一遍整棵树,将覆盖当前区间的所有物品全部加到 (0/1) 背包里面去,这样就可以在任意时间点得到 (0/1) 背包的 dp 数组,回溯的时候撤销当前操作即可。

    时间复杂度 (mathcal O(n^2 log p))

    代码

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    
    inline int read()
    {
    	int data = 0, w = 1; char ch = getchar();
    	while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if (ch == '-') w = -1, ch = getchar();
    	while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    	return data * w;
    }
    
    const int N(4010), M(20010);
    struct node { int l, r, c, h; }; std::vector<node> A;
    int n, P, Q, Rmax, f[N], stk[20][N], top, ans[M]; std::vector<std::pair<int, int> > Qry[M];
    void Insert(int c, int h) { for (int i = 4000; i >= c; i--) f[i] = std::max(f[i], f[i - c] + h); }
    void Push() { for (int i = 1; i <= 4000; i++) stk[top + 1][i] = f[i]; ++top; }
    void Undo() { --top; for (int i = 1; i <= 4000; i++) f[i] = stk[top][i]; }
    
    void Solve(const std::vector<node> &V, int l = 1, int r = Rmax)
    {
    	std::vector<node> L, R; int mid = (l + r) >> 1;
    	for (auto i : V)
    		if (i.l <= l && r <= i.r) Insert(i.c, i.h);
    		else
    		{
    			if (i.l <= mid) L.push_back(i);
    			if (mid < i.r) R.push_back(i);
    		}
    	Push();
    	if (l == r) for (auto i : Qry[l]) ans[i.second] = f[i.first];
    	else Solve(L, l, mid), Solve(R, mid + 1, r);
    	Undo();
    }
    
    int main()
    {
    	n = read(), P = read();
    	for (int i = 1, c, h, t; i <= n; i++)
    	{
    		c = read(), h = read(), Rmax = std::max(Rmax, P - 1 + (t = read()));
    		A.push_back((node) {t, t + P - 1, c, h});
    	}
    	Q = read();
    	for (int i = 1, a, b; i <= Q; i++)
    		a = read(), b = read(), Qry[a].emplace_back(b, i);
    	Solve(A);
    	for (int i = 1; i <= Q; i++) printf("%d
    ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    An easy problem
    Big Event in HDU
    第二个div+css前端项目
    第一个网站前端
    通过jquery.transit.min.js插件,实现图片的移动
    anchor_target_layer中的bounding regression
    faster rcnn结构
    论文灵感
    anchor_target_layer层其他部分解读
    numpy add
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/12763336.html
Copyright © 2011-2022 走看看