POJ 2392 Space Elevator

题目地址:http://poj.org/problem?id=2392

题目大意:有一头奶牛要上太空,他有很多种石头,每种石头的高度是hi,但是不能放到ai之上的高度,并且这种石头有ci个
将这些石头叠加起来,问能够达到的最高高度。

解题思路:先将石头可以放置的最大高度按从小到大的顺序进行排序,

因为只有先放置最大高度最低的才能得到最优解,也就是说让一种石头尽可能高的放。

最大值必须初始化为0,因为存在高度为0的情况。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[400005];
struct node
{
	int h,a,c;
	bool operator<(node &b)
	{
		return a < b.a;
	}
}Arr[420];
int max(int a,int b)
{
	return a > b ? a : b;
}
void zero_one_pack(int cost,int value,int v)
{//0 1背包
	for(int j = v; j >= cost ; j--)
		dp[j] = max(dp[j],dp[j-cost]+value);
}
void com_pack(int cost,int value,int v)
{//完全背包
	for(int j = cost ; j <= v; j++)
		dp[j] = max(dp[j],dp[j-cost]+value);
}
int main()
{
	int k,i,n;
	
	while(scanf("%d",&n)!= EOF)
	{
		int a = 0,c = 0,h = 0;
		for(i = 0; i < n; i++)
		{
			scanf("%d%d%d",&Arr[i].h,&Arr[i].a,&Arr[i].c);
		}
		sort(Arr,Arr+n);//按最高限度从小到大排序
		memset(dp,0,sizeof(dp));
		int M = 0;
		for(i = 0; i < n; i++)	
		{//printf("%d %d %d\n",Arr[i].h,Arr[i].a,Arr[i].c);
			if(Arr[i].c*Arr[i].h >= Arr[i].a)//完全背包
			{
				com_pack(Arr[i].h,Arr[i].h,Arr[i].a);
			}
			else
			{//0 1背包,按二进制方式放物品
				 k = 1; 
				while(k < Arr[i].c)
				{
					zero_one_pack(k*Arr[i].h,k*Arr[i].h,Arr[i].a);
					Arr[i].c -= k;
					k *= 2;
				}
				zero_one_pack(Arr[i].h*Arr[i].c,Arr[i].h*Arr[i].c,Arr[i].a);
			}
			/*
			if(dp[Arr[i].a] > M)
				M = dp[Arr[i].a];
			*/
		}
		//不知道为什么要扫描数组,求解?
		for(i = 0; i <= Arr[n-1].a; i++)
			if(dp[i] > M)M=dp[i];
		printf("%d\n",M);
	}
	return 0;
}


 

原文地址:https://www.cnblogs.com/LUO257316/p/3220839.html