题意
- 有很多种石头,每种石头的高度是hi,但是不能放到ai之上的高度,并且这种石头有ci个
- 将这些石头叠加起来,问能够达到的最高高度
思路
- 看白书上说是稍加思考的题目。。。为什么我觉得还没有优化递推关系的那些题难。。。
- 和一般背包稍有不同的就是对石头按ai排序。。。然后再做。。这个很好理解这里就不多说了。。
- 这样纯做,复杂度有点虚,不过dp常数小。。试了试就过了。。
实现
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 405;
const int maxm = 40005;
struct Node{
int a,c,h;
}node[maxn];
bool operator<(Node x,Node y){
return x.a < y.a;
}
int dp[maxm];
int main(){
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d%d%d",&node[i].h,&node[i].a,&node[i].c);
sort(node+1,node+n+1);
node[0].h = node[0].a = node[0].c = 0;
for (int i=1;i<=n;i++){
for (int j=node[i].a;j>0;j--){
if (j > node[i-1].a)
dp[j] = dp[node[i-1].a];
for (int k=1;k<=node[i].c;k++){
int tmp = j - node[i].h * k;
if (tmp < 0){
break;
}
if (tmp > node[i-1].a)
{
dp[j] = max(dp[node[i-1].a]+node[i].h * k,dp[j]);
}
else{
dp[j] = max(dp[tmp]+node[i].h * k,dp[j]);
}
}
}
}
cout << dp[node[n].a] << "\n";
return 0;
}