codechef December Challenge 2012 Pizza Delivery 完全背包求最小值 这道很重

Pizza Delivery

Problem code: DBOY

  • Submit
  • My Submissions
  • All Submissions

Chef Po had recently started home delivery service for pizzas. Po has only a single delivery boy that delivers the orders by riding his motorcycle. The motorcycle has an unlimited capacity of fuel tank. However, it is too old and can only ride 1 km for each 1 liter of fuel.

There are N fuel stations near the restaurant. The i-th fuel station can fill a fuel tank exactly Ki liters; not more and not less. Filling a fuel tank with any amount of fuel in those stations tends to take a long time. Since the fuel stations are placed near the restaurant, no fuel is needed to go to a fuel station.

Today Chef Po received N pizza orders, which is the same number of fuel stations fortuitously. The house of the person that ordered the i-th order is Hi km away from the restaurant. The delivery boy cannot deliver more than one order at a time. Therefore, after delivering an order, he must return back to the restaurant to take the next order.

The delivery boy is an efficient person and thus he wants to fill the fuel tank with the exact amount of fuel required to deliver an order and return back. He also does not want to spends much time filling the tank, so he wants to minimize the number of times he fills the tank. Help him determine the minimum number of times he must fill the tank to deliver all orders.

Input

The first line contains a single integer T denoting the number test cases. The description of T test cases follows. For each test case, the first line contains a single integer N. The second line contains N space-separated integers Hi. The third line contains N space-separated integers Ki.

Output

For each test case, output a single line containing the minimum number of times the delivery boy must fill the tank.

Constraints

1 ≤ T ≤ 500
1 ≤ N ≤ 500
1 ≤ Hi ≤ 500
1 ≤ Ki ≤ 500
There is at least one way for completing the deliveries.
That is, the delivery boy always can fill a fuel tank exactly 2 * Hi liters for 1 ≤ iN.

Example

Input:

1
4
1 2 3 4
1 4 5 3

Output:

7

Explanation:

Here is one possible solution.

For the first order, the delivery boy must ride 1 + 1 = 2 km long. Fill the tank twice in the first fuel station.

For the second order, the delivery boy must ride 2 + 2 = 4 km long. Fill the tank once in the second fuel station.

For the third order, the delivery boy must ride 3 + 3 = 6 km long. Fill the tank twice in the fourth fuel station.

For the fourth order, the delivery boy must ride 4 + 4 = 8 km long. Fill the tank in the third and fourth fuel stations.

In total, the delivery boy must fill the tank 7 times. There is no way to fill the tank less than 7 times.

http://www.codechef.com/DEC12/problems/DBOY/

题意

输入cas  输入n  输入n个h[i]     再输入n个k[i]   每个h[i]*2   可以用一个或多个k[i]相加得到(也可以是多个自身相加)

问这n个h[i]*2    最少需要多少个k[i]相加得到

比如样例:1 2 3 4  乘2 为 2 4 6 8

2=1+1  最少2个

4=4  最少1个

6=3+3=1+5   最少2个

8=5+3=4+4   最少2个

因此答案是7



思路 :   背包   把数作为背包的体积   对应的背包的值,这里为1 因为要求最小的个数吗 1就是1个 数


注意 千万注意    只要把体积设置为最大 调用一次即可 千万不要对每个h[i]都进行调用  千万注意  再这里吃了很多亏了啊



#include<stdio.h>
#include<string.h>
struct haha
{
	int val;
	int vol;
}k[505];
int n;
int bag[1005];
void _bag()
{
    int i,j,v=1000;
	for(i=1;i<=v;i++)
		bag[i]=999999999;
	bag[0]=0;
    for(i=0;i<n;i++)
    {
        for(j=k[i].vol;j<=v;j++)
        {
            bag[j]=(bag[j-k[i].vol]+k[i].val)<bag[j]?(bag[j-k[i].vol]+k[i].val):bag[j];
        }
    }
}
int main()
{
	int cas,i,j,h[505];
	int rem[1005];
	int num;
	scanf("%d",&cas);
	while(cas--)
	{
		memset(rem,0,sizeof(rem));
        scanf("%d",&n);
		for(i=0;i<n;i++)
		{
			scanf("%d",&num);
			rem[num*2]++;
		}
		for(i=0;i<n;i++)
		{
			scanf("%d",&k[i].vol);
			k[i].val=1;
		}
		int ans=0;
		_bag();//只要调用一次  注意
		   for(i=0;i<=1000;i+=2)
			if(rem[i])
			{
			    ans+=bag[i]*rem[i];
			}
			printf("%d\n",ans);
	}
	return 0;
}




你可能感兴趣的:(codechef December Challenge 2012 Pizza Delivery 完全背包求最小值 这道很重)