我们要先推一个贪心
考虑相邻的两个物品xy 已经耗费p的时间
先做x
a[x]−(p+c[x])∗b[x]+a[y]−(p+c[x]+c[y])∗by
————①
先做y
a[y]−(p+c[y])∗b[y]+a[x]−(p+c[y]+c[x])∗bx
————②
所以①>②的条件是
c[x]∗b[y]<c[y]∗b[x]
所以sort一下 然后就是01背包
关键这个题必须都得用long long!
代码如下
#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
#define in = read();
typedef long long ll;
typedef unsigned int ui;
const ll size = 100000 + 1000;
struct point{ ll a , b , c;}data[size];
ll n , t;
ll ans;
ll f[size];
inline ll read(){
ll num = 0 , f = 1; char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)){
num = num*10 + ch - '0';
ch = getchar();
}
return num*f;
}
inline bool cmp(point x , point y){
return x.c*y.b < y.c*x.b;
}
int main(){
t in; n in;
for(register ll i=1;i<=n;i++) data[i].a in;
for(register ll i=1;i<=n;i++) data[i].b in;
for(register ll i=1;i<=n;i++) data[i].c in;
sort(data + 1 , data + n + 1 , cmp);
for(register ll i=1;i<=n;i++)
for(register ll j=t;j>=data[i].c;j--)
f[j] = max(f[j] , f[j - data[i].c] + data[i].a - data[i].b*j);
for(register ll i=1;i<=t;i++)
ans = max(ans , f[i]);
printf("%d" , ans);
}
//COYG