P4377 [USACO18OPEN] Talent Show G (greedy + 01 backpack + 01 planning)

topic description

Farmer John wants to take his n cows, numbered 1...n for convenience, to the agricultural fair to participate in the annual cattle show! The weight of his ith cow is wi​, and the talent level is ti​, both of which are integers.

Upon arrival, Farmer John was intimidated by the new rules of this year's Da Niu Show:

(i) A group of cows participating in a competition must have a total weight of at least W (this is to ensure that the stronger team is competing, not just a stronger cow), and.

(2) The group with the largest ratio of total talent value to total weight wins.

FJ notices that the total weight of all his cows is not less than W, so he can send a team that meets rule (1). Help him determine the optimum talent-to-weight ratio that can be achieved on such a team.

input format

The first line is two integers, representing the number n of cattle and the total weight limit W.

Lines 2 to (n+1), each line has two integers, and the integer in line (i+1) represents the weight wi​ and talent level t_iti​ of the i cow.

output format

Ask the Farmer to use a group of cows whose total weight is at least W to obtain the ratio of the maximum possible total talent value to the total weight.

If your answer is A, output the value of 1000A rounded down so that the output is an integer (when the number in question is not an integer, the rounding operation removes all decimals when rounding down to an integer part).

Input and output samples

Type #1 to copy

3 15
20 21
10 11
30 31

output #1 copy

1066

Ideas:

There are 2 conditions to consider in this question:

1. A group of cows participating in the competition must have a total weight of at least W

2. The team with the largest ratio of total talent value to total weight wins

The second condition belongs to the question of whether to choose this cow or not to choose it. This is my first 01 score planning problem.

When the first condition is not less than W, dynamic programming can be used but the final result is dp[W]

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f, N = 255, WW = 1005;
int n, W;
struct { int w, t; double y; }cow[N];
double dp[WW];
bool check(double x) {
	int i, j;
	for (int i = 1; i <= n; i++) cow[i].y = (double)cow[i].t - x * cow[i].w;//0/1规划的基础思路
	for (int i = 1; i <= W; i++) dp[i] = -INF;
	dp[0] = 0;
	// 0-1背包的思想 一维
	for (int i = 1; i <= n; i++) {
		for (int j = W; j >= 0; j--) { // 当前背包的大小
			if (j + cow[i].w >= W) dp[W] = max(dp[W], dp[j] + cow[i].y); //超过了这个了贪心是否选这个
			else dp[j + cow[i].w] = max(dp[j+ cow[i].w], dp[j] + cow[i].y);
		}
	}
	return dp[W] < 0; // true x大了 我们要使 x尽可能大
}
int main() {
	cin >> n >> W;
	for (int i = 1; i <= n; i++) cin >> cow[i].w >> cow[i].t;
	double L = 0, R = 0;
	for (int i = 1; i <= n; i++) R += cow[i].t;
	for (int i = 0; i < 50; ++i) {
		double mid = L + (R - L) / 2;
		if (check(mid)) R = mid;
		else L = mid;
	}
	cout << (int)(L * 1000) << endl;
	return 0;
}

Guess you like

Origin blog.csdn.net/zhi6fui/article/details/128616811