题目大概意思是有K种不同的石块,现在用这些石块堆成一个塔,每块石头的高度hi,数量ci,以前最高不能超过ai高度,超过后会被光线损坏,求最高能堆多高。
这题也是个背包问题,只不过有一个最高度限制,所以在堆积过程中,应该让ai越小的石头越先选择放在底下,只要对ai进行一下排序后再背包就可以了,过程中
还是要判断一下有没有超过最大高度限制。
#ifndef HEAD
#include <stdio.h>
#include <vector>
#include <math.h>
#include <string.h>
#include <string>
#include <iostream>
#include <queue>
#include <list>
#include <algorithm>
#include <stack>
#include <map>
using namespace std;
#endif // !HEAD
#ifndef QUADMEMSET
inline void QuadMemSet(void* dst, int iSize, int value)
{
iSize = iSize / 4;
int* newDst = (int*)dst;
#ifdef WIN32
__asm
{
mov edi, dst
mov ecx, iSize
mov eax, value
rep stosd
}
#else
for (int i = 0; i < iSize; i++)
{
newDst[i] = value;
}
#endif
}
#endif
int DP[40002];
struct FFS
{
int Hi;
int Ai;
int Ci;
};
bool ffccomp(const FFS& a1, const FFS& a2)
{
return a1.Ai < a2.Ai;
}
int main()
{
#ifdef _DEBUG
freopen("e:\\in.txt", "r", stdin);
#endif
int n;
scanf("%d\n", &n);
vector<FFS> ffs;
FFS f;
f.Ai = -1;
ffs.push_back(f);
for (int i = 1; i <= n; i++)
{
FFS f;
ffs.push_back(f);
scanf("%d %d %d\n", &ffs[i].Hi, &ffs[i].Ai, &ffs[i].Ci);
}
//QuadMemSet(FF, sizeof(FF), -1);
QuadMemSet(DP, sizeof(DP), -1);
sort(ffs.begin(), ffs.end(), ffccomp);
DP[0] = 0;
int maxHei = -1;
for (int i = 1; i <= n; i++)
{
//QuadMemSet(FF[i & 1], sizeof(FF) / 2, -1);
//FF[i & 1][0] = ffs[i].Ci;
for (int h = 0; h <= ffs[i].Ai;h++)
{
if (DP[h] >= 0)
{
DP[h] = ffs[i].Ci;
}
else if (h <= ffs[i].Ai)
{
if (h < ffs[i].Hi || DP[h - ffs[i].Hi] <= 0)
{
DP[h] = -1;
}
else
DP[h] = DP[h - ffs[i].Hi] - 1;
}
else
DP[h] = -1;
if (DP[h] >= 0 && h > maxHei)
{
maxHei = h;
}
}
}
printf("%d\n", maxHei);
return 0;
}