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;
}

  

编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4765493.html