题目地址: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;
}