算法问题分析--邮票问题

问题如下:

There are N number kinds of stamps with different worth. At this moment, you are allowed to use the same kinds of stamps several times, but the total number of uses of all stamps is restricted to less than K number.
Within this limitation, you want to know the maximum worth by making the worth one by one starting from 1 using the stamps.
For example, N=2 is given, the worth of each stamp is 1, 3 and K=5 is decided. Then you can make the worth up to 5 by using the stamps whose worth is 1, and you can find it out from 6 to 13 as the below:

6 = 3+3
7 = 3+3+1
8 = 3+3+1+1
9 = 3+3+3
10 = 3+3+3+1
11 = 3+3+3+1+1
12 = 3+3+3+3
13 = 3+3+3+3+1

However, you cannot make 14 using 5 stamps. Therefore, the maximum worth you can make is 13.

Time limit: 1 second (java: 2 seconds)

Input format

Several test cases can be included in the inputs. T, the number of cases is given in the first row of the inputs. After that, the test cases as many as T (T ≤ 30) are given in a row.
The maximum use number, K and the number of kinds of stamps, N are given by being separated with a blank on the first row per each test case. (1 ≤ N ≤ 50, 1 ≤ K ≤ 200)
Each stamp worth is given by being separated with a blank on the second row. Each worth is a natural number below 10,000.

Output format

Output the maximum worth you can when making worth using stamps in order on the first row per each test case.

Example of Input

2
5 2
1 3
3 10
29 50 36 43 1 2 4 8 15 22

Example of Output

13

56

分析 1:

先想到的是用递归的方法求解。先设置一个数组,把所有能表示的数值用递归求出来,以这个值为index,把数组设置为1。最后找出第一个值为0的数组元素。

那么前一个就是所能表达的最大值。

但是,这种方法效率很低。

#include 

#define MAX_N 50
#define MAX_K	200

#define MAX_VALUE (200 * 10000)

int result[MAX_VALUE];
int stamp_value[MAX_N];

void calc_value(int K, int N, int value)
{
	int i;
	if(K == 0)
	{
		//for(i = 0; i < N; i++)
		//{
			result[value] =1;
		//}
	}
	else
	{
		for(i = 0; i < N; i++)
		{
			result[value + stamp_value[i]] = 1;
			calc_value(K -1, N, value + stamp_value[i]);
			//result[value + stamp_value[i]] = 1;
		}
	}
}
int main(void)
{
	FILE *fp = freopen("input6.txt", "r", stdin);

	if(fp == NULL)
	{
		printf("open file failed\n");
		return -1;
	}

	int test_count;
	scanf("%d", &test_count);

	int i;
	for(i = 0; i < test_count; i++)
	{
		memset(stamp_value, 0, sizeof(stamp_value));

		int K, N;
		scanf("%d %d", &K, &N);
		
		int j;
	//	int stamp_value[MAX_N];
		
		for(j = 0; j < N; j++)
		{
			scanf("%d", stamp_value + j);	
		}

		int value = 0;
		calc_value(K, N, value); 
		
		for(j = 1; j < sizeof(result)/sizeof(result[0]); j++)
		{
			if(result[j] == 0)
			{
				printf("%d\n", j - 1); 
				break;
			}
		} 
	}

	fclose(fp);
	return 0;
}

分析2:

这个问题和 0-1背包问题有点相似。 要求在约束条件下,最大的连续邮票值的范围,可以转化为求在约束条件下,不能用给定的邮票表示的最小值。

假定 x[j]为第j个邮票的值,V(n)为邮票值为n的时候对应的邮票的个数,那么

V(n) = min{V(n - x[j]) + 1}   (n >= x[j])

#include 

#define MAX_N 50
#define MAX_K	200

#define MAX_VALUE (200 * 10000)

int main(void)
{
	FILE *fp = freopen("input6.txt", "r", stdin);

	if(fp == NULL)
	{
		printf("open file failed\n");
		return -1;
	}

	int test_count;
	scanf("%d", &test_count);

	int i;
	for(i = 0; i < test_count; i++)
	{
		int K, N;
		scanf("%d %d", &K, &N);
		
		int j;
		int stamp_value[MAX_N];
		
		for(j = 0; j < N; j++)
		{
			scanf("%d", stamp_value + j);	
		}

		int stamp_count[MAX_VALUE] = {0, };
		
		int current_value = 0;
		while (1)
		{
			current_value++;
			
			
			for(j = 0; j < N; j++)
			{
				if(current_value >= stamp_value[j])
				{
					if(stamp_count[current_value] == 0)
					{
						stamp_count[current_value] = stamp_count[current_value - stamp_value[j]] + 1;
					}
					if(stamp_count[current_value] > stamp_count[current_value - stamp_value[j]] + 1)
					{
						stamp_count[current_value] = stamp_count[current_value - stamp_value[j]] + 1;
					}
				}
			} 

			if(stamp_count[current_value] == 0 || stamp_count[current_value] > K)
			{
				printf("max value: %d\n", current_value - 1);
				break;
			}
		}
		
	}

	fclose(fp);
	return 0;
}


References:

1. http://blog.csdn.net/fisher_jiang/article/details/1119762

你可能感兴趣的:(stamp,problem,Algorithms)