Greedy (5) Pan-knapsack problem

table of Contents

1. Pan-knapsack problem

Second, OJ actual combat

CSU 1775: A sad move

CSU 1926: Use the fewest coins

CodeForces 538B Quasi Binary


1. Pan-knapsack problem

This type of greedy problem is somewhat similar to the knapsack problem, but it is not a real knapsack problem.

The real knapsack problem is basically an overall planning problem.

 

Second, OJ actual combat

CSU 1775: A sad move

topic:

Description

For csuxushu, being able to go to CSU (California State University) is the honor of his life, and changing campus and moving the dormitory is his greatest misfortune. Successfully passed the provincial selection, the happy csuxushu now needs to prepare for the move.
For the studious csuxushu, the only headache is the handling of books, because he has too many books. In order to prevent the books from being damaged during transportation, he plans to customize a special storage box. For the sake of simplicity, we assume that all his books have the same specifications. Due to mass customization, these storage boxes have the same length L, and the width and thickness are the width and thickness of a book. csuxushu has a special requirement, that is, each storage box can only hold two books at most. Of course, he needs to transport all N books, and the total length of books in each storage box cannot exceed L.
Although the school team members gave csuxushu many rewards, csuxushu still wanted to save as few storage boxes as possible in order to save money. However, he was obviously confused when facing such a difficult problem. At this time, he thought of you-all CSU’s best programmers came to help him solve this problem.

Input

An integer T in the first line represents T groups of data, followed by a blank line and there is a blank line between each set of data.
The first row of each group of data is an integer n (1 ≤ n ≤ 10^5), which means there are n books. The second line is an integer L, 1≤l ≤ 10000, which is the length of the special storage box. The next n lines are the length of each book li, li≤l.

Output

Each group of data outputs one line, that is, how many storage boxes should be set by csuxushu at least.

Sample Input

1

10
80
70
15
30
35
10
80
20
35
10
30

Sample Output

6

This topic is also quite boring, the required output format is that there is a blank line between the 2 numbers.

This topic is to sort first and then use the greedy algorithm. Although it is difficult to say clearly, the algorithm should be correct.

Code:

#include<iostream>
#include<algorithm>
using namespace std;
 
int list[100000];
 
int main()
{
    int t, n, l;
    int low, high;
    int sum;
    cin >> t;
    for (int ii = 0; ii < t;ii++)
    {
        cin >> n >> l;
        for (int i = 0; i < n; i++)cin >> list[i];
        sort(list, list + n);
        low = 0;
        high = n - 1;
        sum = 0;
        while (low < high)
        {
            if (list[low] + list[high] <= l)low++;
            high--;
            sum++;
        }
        if (low == high)sum++;
        cout << sum << endl<<endl;
    }
    return 0;
}

CSU 1926: Use the fewest coins

topic:

Description

In the country where Little X lives, many denominations have coins. There are four kinds of coins in Little X's piggy bank, which are 5 yuan, 10 yuan, 20 yuan and 50 yuan. When he wants to pay, he always wants to use the least amount of coins. Now tell you the number of the four coins owned by Little X, please help Little X find the best payment plan (maybe the plan does not exist).

Input

The input contains no more than 10 sets of data. Each group of data consists of a row of five integers A, B, C, D, and S separated by spaces (0<=A,B,C,D<=1000000,1<=S<=10000000), respectively representing small The number of 5 yuan coins, 10 yuan coins, 20 yuan coins, and 50 yuan coins owned by X, as well as the amount of money that small X needs to pay now (unit: yuan).

Output

For each set of data, if the small X cannot be paid, output a line with an integer -1; otherwise, output a line of five integers a, b, c, d, and s separated by spaces, respectively representing the small X needs to be used in the payment plan The number of 5 yuan coins, 10 yuan coins, 20 yuan coins, and 50 yuan coins, as well as the total number of coins that the small X needs to spend.

Sample Input

1 2 3 4 35
1 2 3 4 567

Sample Output

1 1 1 0 3
-1

Code:

#include<iostream>
#include<algorithm>
using namespace std;
 
int main()
{
	int A, B, C, D, S;
	while (cin >> A >> B >> C >> D >> S)
	{
		if (S % 5 || S % 2 && A == 0)
		{
			cout << -1 << endl;
			continue;
		}
		S /= 5;  //1,2,4,10
		int a, b, c, d, s;
		if (A > S % 2 + 1 || B > 0)//贪心
		{
			d = min(S / 10, D), S -= d * 10;
			c = min(S / 4, C), S -= c * 4;
			b = min(S / 2, B), S -= b * 2;
			a = min(S, A), S -= a;
			s = a + b + c + d;
			if (S)cout << -1 << endl;
			else cout << a << " " << b << " " << c << " " << d << " " << s << endl;
			continue;
		}
		a = S % 2, S /= 2;//2,5
		if (S % 2 && D == 0)
		{
			cout << -1 << endl;
			continue;
		}
		d = min((S-S%2*5) / 10, (D - S % 2) / 2) * 2 + S % 2, S -= d * 5;
		c = min(S / 2, C), S -= c * 2;
		b = 0;
		s = a + b + c + d;
		if (S)cout << -1 << endl;
		else cout << a << " " << b << " " << c << " " << d << " " << s << endl;
	}
	return 0;
}

CodeForces 538B Quasi Binary

topic:

Description

A number is called quasibinary if its decimal representation contains only digits 0 or 1. For example, numbers 0, 1, 101, 110011 — are quasibinary and numbers 2, 12, 900 are not.

You are given a positive integer n. Represent it as a sum of minimum number of quasibinary numbers.

Input

The first line contains a single integer n (1 ≤ n ≤ 106).

Output

In the first line print a single integer k — the minimum number of numbers in the representation of number n as a sum of quasibinary numbers.

In the second line print k numbers — the elements of the sum. All these numbers should be quasibinary according to the definition above, their sum should equal n. Do not have to print the leading zeroes in the numbers. The order of numbers doesn't matter. If there are multiple possible representations, you are allowed to print any of them.

Sample Input

Input

9

Output

9
1 1 1 1 1 1 1 1 1 

Input

32

Output

3
10 11 11

For this subject, we must first make it clear that no matter how many numbers are input, the numbers we ask for add up to this number, and there will never be any carry phenomenon during the process of adding up.

It is not difficult to prove it, but it should not be necessary.

In short, it can be easily solved by using this property.

Code:

#include<iostream>
#include<stack>
using namespace std;
 
stack<int>s;
 
int ff(int a, int b, int c, int d, int e, int f)
{
	int min = 10;
	if (a > 0 && min > a)min = a;
	if (b > 0 && min > b)min = b;
	if (c > 0 && min > c)min = c;
	if (d > 0 && min > d)min = d;
	if (e > 0 && min > e)min = e;
	if (f > 0 && min > f)min = f;
	if (min == 10)return 0;
	int x = (a >= min) * 100000 + (b >= min) * 10000 + (c >= min) * 1000 + (d >= min) * 100 + (e >= min) * 10 + (f >= min);
	for (int i = 0; i < min; i++)s.push(x);
	return ff(a - (a >= min)*min, b - (b >= min)*min, c - (c >= min)*min, d - (d >= min)*min, e - (e >= min)*min, f - (f >= min)*min) + min;
}
 
int main()
{
	int n;
	cin >> n;
	int a, b, c, d, e, f;
	if (n == 1000000)cout << 1 << endl << 1000000;
	else
	{
		f = n % 10;
		e = n / 10 % 10;
		d = n / 100 % 10;
		c = n / 1000 % 10;
		b = n / 10000 % 10;
		a = n / 100000;
		cout << ff(a, b, c, d, e, f) << endl;
		while (!s.empty())
		{
			cout << s.top() << " ";
			s.pop();
		}
	}
	return 0;
}

Of course, if you think about it carefully, this question does not need a stack.

Code:

#include<iostream>
#include<stack>
using namespace std;
 
void ff(int a, int b, int c, int d, int e, int f)
{
	int s = 0;
	if (a + b + c + d + e + f == 0)return;
	if (f)
	{
		f--;
		s += 1;
	}
	if (e)
	{
		e--;
		s += 10;
	}
	if (d)
	{
		d--;
		s += 100;
	}
	if (c)
	{
		c--;
		s += 1000;
	}
	if (b)
	{
		b--;
		s += 10000;
	}
	if (a)
	{
		a--;
		s += 100000;
	}
	cout << s << " ";
	ff(a, b, c, d, e, f);
}
 
int main()
{
	int n;
	cin >> n;
	int a, b, c, d, e, f;
	if (n == 1000000)cout << 1 << endl << 1000000;
	else
	{
		f = n % 10;
		e = n / 10 % 10;
		d = n / 100 % 10;
		c = n / 1000 % 10;
		b = n / 10000 % 10;
		a = n / 100000;
		int max = 0;
		if (max < a)max = a;
		if (max < b)max = b;
		if (max < c)max = c;
		if (max < d)max = d;
		if (max < e)max = e;
		if (max < f)max = f;
		cout << max << endl;
		ff(a, b, c, d, e, f);
		cout << endl;
	}
	return 0;
}

This code looks much simpler.

In fact, the difference is not big, but this code more clearly reflects a greedy strategy:

Output a number every time so that it has as many 1 as possible, of course, if it meets the conditions of the question.

Guess you like

Origin blog.csdn.net/nameofcsdn/article/details/112753449