• HDU 4341 Gold miner(分组背包)


    题目链接 Gold miner

    目标是要在规定时间内获得的价值总和要尽可能大。

    我们先用并查集把斜率相同的物品分在同一个组。

    这些组里的物品按照y坐标的大小升序排序。

    如果组内的一个物品被选取了,那该组排在他前面的所有物品肯定被选取了。

    那么我们对每个组的所有物品,对价值和代价分别求前缀和。

    那么选了3号,就相当于选了1,2,3号。

    这个时候问题就转化为分组背包了。

    也就是说把物品转换后,这个组内我最多只能选1个物品。

    然后就很简单了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    typedef long long LL;
    
    const int N = 205;
    
    struct node{ int x, y, t, v; } a[N];
    
    int father[N], used[N], c[N], f[N], g[N], dp[N * N];
    int n, t, cnt, et, ca = 0;
    vector <int> v[N];
    
    int getfather(int x){ return father[x] ? father[x] = getfather(father[x]) : x; }
    bool cmp(int p, int q){ return a[p].y < a[q].y;}
    
    int main(){
    
    	while (~scanf("%d%d", &n, &t)){
    		rep(i, 1, n) scanf("%d%d%d%d", &a[i].x, &a[i].y, &a[i].t, &a[i].v);
    		memset(father, 0, sizeof father);
    
    		rep(i, 1, n - 1){
    			rep(j, i + 1, n){
    				if (a[i].x * a[j].y == a[i].y * a[j].x){
    					int fa = getfather(i), fb = getfather(j);
    					if (fa ^ fb){
    						father[fa] = fb;
    					}
    				}
    			}
    		}
    
    		rep(i, 1, n) c[i] = getfather(i);
    
    		rep(i, 0, n + 1) v[i].clear();
    		cnt = 0;
    		memset(used, 0, sizeof used);
    		rep(i, 1, n){
    			if (!used[c[i]]){
    				used[c[i]] = ++cnt;
    				v[cnt].push_back(i);
    			}
    
    			else{
    				v[used[c[i]]].push_back(i);
    			}
    		}
    
    		rep(i, 1, cnt) if ((int)v[i].size() > 1) sort(v[i].begin(), v[i].end(), cmp);
    		
    		memset(dp, 0, sizeof dp);
    		rep(i, 1, cnt){
    			dec(j, t, 0){
    				int C = 0, V = 0;
    				for (auto u : v[i]){
    					C += a[u].t;
    					V += a[u].v;
    					if (j >= C) dp[j] = max(dp[j], dp[j - C] + V);
    				}
    			}
    		}
    		printf("Case %d: %d
    ", ++ca, dp[t]);	
    	}
    	return 0;
    }
    
  • 相关阅读:
    html5中将图片的绝对路径转换成文件对象
    Vue中之nextTick函数源码分析
    javascript中的异步 macrotask 和 microtask 简介
    HTML5可预览多图片ajax上传(使用formData传递数据)
    vue双向绑定的原理及实现双向绑定MVVM源码分析
    理解Vue中的Render渲染函数
    如何实现一个 Virtual DOM 及源码分析
    diff.js 列表对比算法 源码分析
    理解spread运算符与rest参数
    go语言之进阶篇普通变量的方法集
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/7360323.html
Copyright © 2020-2023  润新知