题目
题解思路
一开始想直接用 L排序
S 和 L 肯定有关系的 所以不能直接做
大佬直接推出最优的选择次序了。
这样我们只要在这些答案里选出最优即可。
因为有些会被消耗完。
求恰好的背包DP,为了保证状态都是从起点转移的,要把非起点初始化为无穷大以避免转移
而且 这里我们是用最大的体积来枚举所有选择方法,所以恰好用最大的体积时不一定最优,还要往前寻找。
墨染空大佬的文章
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
struct node
{
int s,w,l;
}a[110];
int f[10100];
bool cmp (node A , node B)
{
return A.s*B.l < B.s * A.l;
}
int main ()
{
ios::sync_with_stdio(false);
int T,ca = 1 ;
cin>>T;
while(T--)
{
memset(f , -0x3f , sizeof(f) );
int n,m = 0 , ans = 0 ;
cin>>n;
for (int i = 1 ; i <= n ; i++ )
{
int t1,t2,t3;
cin>>t1>>t2>>t3;
a[i].s = t1 ;
a[i].w = t2 ;
a[i].l = t3 ;
m += t1 ;
}
sort( a+1 , a+1+n , cmp );
f[0] = 0 ;
for (int i = 1 ; i <= n ; i++ )
{
for (int j = m ; j >= a[i].s ; j-- )
{
f[j] = max( f[j] , f[j-a[i].s] + max( 0 , a[i].w - (j-a[i].s)*a[i].l) );
}
}
for (int i = m ; i >= 0 ; i-- )
ans = max(ans , f[i] );
cout<<"Case #"<<ca<<": "<< ans <<"\n";
ca++;
}
return 0 ;
}