ZCMU-2165:黃金礦工(變形01揹包)

2165: 黃金礦工

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 58  Solved: 28
[Submit][Status][Web Board]

Description

Input

3 10 

1 1 1 1 

2 2 2 2 

1 3 15 9

Output

3

 

Sample Input

Sample Output

HINT

 

-----sample2------

 

1 1 13 1

2 2 2 2

1 3 4 7

 

-----sample2-----

 

7

 

-----------

 

30%的數據,0 < T ≤ 4000 

 

 

 

100%的數據,N ≤ 200, 0 < T ≤ 40000 

 

Source

TJOI2013

 

【解析】

先處理每個點,算出每個點的斜率和距離原點的距離

然後先按斜率爲第一順序排序,然後是距離。

接着就是01揹包問題了。

但是有點不同的是在相等角度的情況下,後者加上前者的 t 和 v(因爲先抓前面那個才能抓後面的),把它看成一個整體的狀態來思考,最後通過 mk[i] 來控制跳躍到上一個不相等的元素。

#include<bits/stdc++.h>
using namespace std;
const int maxt = 400 + 10;
struct node
{
	double a;
	int t, v, s;
};
int cmp(node x, node y)
{
	if (x.a == y.a)
		return x.s < y.s;
	return x.a < y.a;
}
int main()
{
	node nds[300];
	int n, m, x, y;
	int dp[300][maxt];//黃金數,時間

	while (~scanf("%d%d", &n, &m))
	{
		memset(dp, 0, sizeof(dp));
		for (int i = 1; i <= n; i++)
		{
			scanf("%d%d%d%d", &x, &y, &nds[i].t, &nds[i].v);
			nds[i].a = y * 1.0 / x;
			nds[i].s = y * y + x * x;
		}
		sort(nds + 1, nds + 1 + n, cmp);//排序,角度優先,其次是距離原點的距離
		int idx = 1, mk[300];
		mk[1] = 1; // 與 nds[i] 同步
		for (int i = 2; i <= n; i++)
			if (nds[i].a != nds[i - 1].a)//角度不同編號不同
				mk[i] = ++idx;
			else
				mk[i] = idx;//角度相同編號相同

		for (int i = 1; i <= n; i++)
		{
			if (nds[i].a == nds[i - 1].a)//在同一條直線上(肯定是躲在後面那個)
			{
				nds[i].t += nds[i - 1].t;//在同一直線的時間加到後面那個一起
				nds[i].v += nds[i - 1].v;//同一直線的價值加到後面那個一起
				for (int j = m; j >= 0; j--)//01揹包模板
				{
					if (j >= nds[i].t)
					{
						dp[i][j] = max(dp[i - 1][j], dp[mk[i] - 1][j - nds[i].t] + nds[i].v); // mk[i]-1 可以打印dp看看分析下,因爲要跳過前一個相同的,因爲已經把前一個的t和v加上去了,表示把多個看爲一個整體
						//cout << mk[i] - 1 << "   mk" << endl;
					}
					else
						dp[i][j] = dp[i - 1][j];
				}
			}
			else//不在同一條直線上
				for (int j = m; j >= 0; j--)
				{
					if (j >= nds[i].t)
						dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - nds[i].t] + nds[i].v);
					else
						dp[i][j] = dp[i - 1][j];
				}
		}
		printf("%d\n", dp[n][m]);
	}

	return 0;
}

 

發佈了89 篇原創文章 · 獲贊 11 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章