「luogu1417」烹调方案
题目链接 :https://www.luogu.org/problemnew/show/P1417
直接背包 -> 30'
考虑直接背包的问题:在DP时第i种食材比第j种食材更优,但由于j<i导致第j种食材先被决策到,故 GG
显然:当i,j满足 f[t]+a[i]-b[i]*(c[i]+t) > f[t]+a[j]-b[j]*(c[j]+t) <=> b[i]*c[i] < b[j]*c[j] 第i种更优;
1 //Author : 15owzLy1 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <algorithm> 7 #include <queue> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #define lson tl, mid, rt<<1 12 #define rson mid+1, tr, rt<<1|1 13 #define pb(__) push_back(__) 14 #define fr() front() 15 #define bg() begin() 16 #define it iterator 17 #define INF 2100000000 18 typedef long long ll; 19 typedef double db; 20 template<class T>inline void get_max(T &_, T __) { _=_>__?_:__; } 21 template<class T>inline void get_min(T &_, T __) { _=_<__?_:__; } 22 template<class T>inline void Swap(T &_, T &__) { T ___=_;_=__;__=___; } 23 template<class T>inline T abs(T _) { return _>0?_:-_; } 24 template<typename T>inline void read(T &_) { 25 _=0;bool __=0;char ___=getchar(); 26 while(___<'0'||___>'9'){__|=(___=='-');___=getchar();} 27 while(___>='0'&&___<='9'){_=(_<<1)+(_<<3)+(___^48);___=getchar();} 28 _=__?-_:_; 29 } 30 31 const int N = 55, M = 100005; 32 struct node { 33 int a, b, c; 34 bool operator < (const node x) const { 35 return 1ll*this->c*x.b < 1ll*this->b*x.c; 36 } 37 }dish[N]; 38 int T, n; 39 ll res, f[M]; 40 41 int main() { 42 //freopen(".in","r",stdin); 43 //freopen(".out","w",stdout); 44 read(T), read(n); 45 for(int i=1;i<=n;i++) read(dish[i].a); 46 for(int j=1;j<=n;j++) read(dish[j].b); 47 for(int k=1;k<=n;k++) read(dish[k].c); 48 std::sort(dish+1, dish+1+n); 49 for(int i=1;i<=n;i++) 50 for(int j=T;j>=dish[i].c;j--) { 51 get_max(f[j], f[j-dish[i].c]+1ll*dish[i].a-1ll*j*dish[i].b); 52 get_max(res, f[j]); 53 } 54 printf("%lld\n", res); 55 fclose(stdin); 56 fclose(stdout); 57 return 0; 58 }