zoukankan      html  css  js  c++  java
  • 01背包(分组) HDOJ 4341 Gold miner

    题目传送门

    题意:有n个金矿,每个金矿有抓取的消耗的时间和价值,矿工在原点,问在T时间内能得到的最大的价值

    分析:唯一和01背包不同的是金矿可能共线,也就是抓取近的金矿后才能抓后面共线的金矿。这是分组背包问题,方法是将点按照斜率排序,如果相等按照距离原点远近排序,将斜率相等的点分成一组,每组的点累加上前面的点的时间和价值,这样每组只选一个点,就是01背包了

    收获:分组背包问题

    代码:

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015-8-27 8:48:05
    * File Name     :J.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 2e2 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    const double eps = 1e-6;
    struct Point	{
    	int x, y, t, v;
    	bool operator < (const Point &r) const	{
    		if (y * r.x == x * r.y)	return y < r.y;
    		else	return y * r.x < x * r.y;
    	}
    	bool operator == (const Point &r) const	{
    		return y * r.x == x * r.y;
    	}
    }p[N];
    int dp[40010];
    vector<Point> block[N];
    
    int main(void)    {
    	int n, T, cas = 0;
    	while (scanf ("%d%d", &n, &T) == 2)	{
    		for (int i=1; i<=n; ++i)	{
    			scanf ("%d%d%d%d", &p[i].x, &p[i].y, &p[i].t, &p[i].v);
    		}
    		sort (p+1, p+1+n);
    
    		int cnt = 0;
    		for (int i=1; i<=n; ++i)	block[i].clear ();
    		block[++cnt].push_back (p[1]);
    		for (int i=2; i<=n; ++i)	{
    			if (p[i] == p[i-1])	block[cnt].push_back (p[i]);
    			else	block[++cnt].push_back (p[i]);
    		}
    		for (int i=1; i<=cnt; ++i)	{
    			for (int j=1; j<block[i].size (); ++i)	{
    				block[i][j].t += block[i][j-1].t;
    				block[i][j].v += block[i][j-1].v;
    			}
    		}
    
    		memset (dp, 0, sizeof (dp));
    		for (int i=1; i<=cnt; ++i)	{
    			for (int j=T; j>=0; --j)	{
    				for (int k=0; k<block[i].size (); ++k)	{
    					if (j >= block[i][k].t)
    						dp[j] = max (dp[j], dp[j-block[i][k].t] + block[i][k].v);
    				}
    			}
    		}
    
    		printf ("Case %d: %d
    ", ++cas, dp[T]);
    	}
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    【NYOJ】[22]素数求和问题
    【NYOJ】[13]Fibonacci数
    【NYOJ】[13]Fibonacci数
    【CodeForces】[606A]Magic Spheres
    【CodeForces】[606A]Magic Spheres
    【杭电】[1201]18岁生日
    【杭电】[1201]18岁生日
    【杭电】[1994]利息计算
    【杭电】[1994]利息计算
    新型量子云装置问世 让你免费体验量子计算机
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4765493.html
Copyright © 2011-2022 走看看