The fifth training match (thinking, greedy, longest common subsequence)

Question A

Idea: q/x is rounded up, we find all the maximum and minimum values, only need to use the error generated by this rounding, each number is divided by x and rounded up is the maximum, the sum of all numbers is divided Rounding up x is the smallest. Round up
: (a + b-1) / b is a/b rounded up
(a + b / 2) / 2 is a / b rounded up

#include<cstdio>
#include<iostream>
#include<string>
#include<stack>
using namespace std;
typedef long long ll;
int t;
ll a[1000000], x, n;
void work()
{
    
    
	cin >> n >> x;
	ll max1 = 0, min1 = 0, sum = 0;
	for(int i = 1; i <=n ; ++i) 
	{
    
    
		scanf("%lld", &a[i]);
		sum += a[i];
		max1 += (a[i] + x - 1) / x;
	}
	min1 = (sum + x - 1) / x;
	cout << min1 << " " << max1 << endl;
	
}
int main()
{
    
    
	ios::sync_with_stdio(false);
    cin >> t;
    while(t--) work();
    return 0;
}

Question B

Question: Give you an array and x, your initial score is 0. Traverse the array from the beginning. For the current element, it ends when x cannot be divisible, and the score is output; if x can be divisible, the score increases by the current number size, and x elements of size a[i] divided by x are added to the end of the array.

If we simulate the array according to the meaning of the question, it will definitely burst...In fact, we don't need to constantly update the array a, we can use an array b to record the current size of a[i] element with b[i]. In this way, if a[i] can divide x evenly, then update a[i] to a[i]/x, b[i]=b[i]*x.
Note here that the initial score is actually the sum of the array elements, b[i] is initially 1, and the actual operation will not enter until the initialization is completed~

#include <bits/stdc++.h>
using namespace std;
#define qc std::ios::sync_with_stdio(0);
int a[100001];
int b[100001];

int main() {
    
    
	qc;
	cin.tie(0);
	int t;
	cin >> t;
	while (t--) {
    
    
		int n, k;
		long long ans = 0;
		cin >> n >> k;
		for (int i = 0; i < n; i++) {
    
    
			cin >> a[i];
			b[i] = 1;
			ans += a[i];
		}
		int flag = 0;
		while (1) {
    
    
			for (int i = 0; i < n; i++) {
    
    
				if (a[i] % k != 0) {
    
    
					flag = 1;
					break;
				} else {
    
    
					a[i] = a[i] / k;
					b[i] = b[i] * k;
					ans += b[i] * a[i];
				}
			}
			if (flag == 1)
				break;
		}
		cout << ans << endl;
	}
}

Question C The
meaning of the question:
n people, m gifts, each gift corresponds to the value c[i] (given in increments), and each person corresponds to a number a[i]. You can send a gift with a number <=a[i], You can also send c[a[i]] cash directly, how to send gifts to minimize the cost

Idea: Gifts are unique, greedy to distribute gifts, and assign the cheapest gift to the person with the highest number

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
int n, m;
int a[N], c[N];
int main() {
    
    
	int t; cin >> t;
	while (t--) {
    
    
		cin >> n >> m;
		for (int i = 1; i <= n; ++i)cin >> a[i];
		for (int i = 1; i <= m; ++i)cin >> c[i];
		sort(a + 1, a + 1 + n, greater<int>());
		ll res = 0;
		for (int i = 1, j = 1; i <= n; ++i) {
    
    
			if (a[i] > j) {
    
    
				res += c[j];
				++j;
			}
			else res += c[a[i]];
		}
		cout << res << endl;
	}
	return 0;
}

Question H The
meaning of the question: Given the r sequence and the b sequence, now without changing the internal order of the r and b sequences, the r and b sequences are put together into the a sequence, so that the maximum prefix of the a sequence is the largest. Solve for this value.

Solution: Solve the maximum prefix sum of r sequence and b sequence separately, and add them together.

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int t;
ll a[1000], x, n, m, b[1000];
void work()
{
    
    
	memset(a, 0, sizeof(a));
	cin >> n;
	ll max1 = 0, max2 = 0;
	for(int i = 1; i <= n; ++i)
	{
    
    
		scanf("%lld", &a[i]);
		a[i] += a[i-1];
		max1 = max(max1, a[i]);
	}
	cin >> m;
	for(int i = n+2; i <= n+m+1; ++i)
	{
    
    
		scanf("%lld", &a[i]);
		a[i] += a[i-1];
		max2 = max(max2, a[i]);
	}
	cout << max1 + max2 << endl;
}
int main()
{
    
    
	ios::sync_with_stdio(false);
    cin >> t;
    while(t--) work();
    return 0;
}

G title
poj 1458

Guess you like

Origin blog.csdn.net/cosx_/article/details/113401964