一看到这道题就是01背包
但是我注意到价值和当前的时间有关。
没有想太多,直接写,0分然后发现输入方式不对……
改了之后只有25分 我知道wa是因为时间会影响价值,但不知道怎么做。后来看了题解,发现我对01背包理解不够透彻
普通01背包做下来放入物品的顺序是1到n的 因为这个时候顺序没有关系,所以可以直接做 但是这道题后面放的物品价值小,所以价值有关系 所以就要提前排好序。 排序的依据就判断相邻两个物品先后放的价值, 然后化简可以推出一个式子。 这里其实是一个贪心。 然后就做01背包就好了然后注意开long long
#include#include #include #define REP(i, a, b) for(int i = (a); i < (b); i++)#define _for(i, a, b) for(int i = (a); i <= (b); i++)using namespace std;typedef long long ll;const int MAXN = 112;const int MAXM = 112345;ll f[MAXM];struct node { ll a, b, c; bool operator < (const node& rhs) const { return c * rhs.b < rhs.c * b; }}s[MAXN];int t, n;int main(){ scanf("%d%d", &t, &n); REP(i, 0, n) scanf("%lld", &s[i].a); REP(i, 0, n) scanf("%lld", &s[i].b); REP(i, 0, n) scanf("%lld", &s[i].c); sort(s, s + n); ll ans = 0; REP(i, 0, n) for(int j = t; j >= s[i].c; j--) { f[j] = max(f[j], f[j-s[i].c] + s[i].a - j * s[i].b); ans = max(ans, f[j]); } printf("%lld\n", ans); return 0;}