洛谷 P1417 烹调方案 (01背包拓展)

一看到这道题就是01背包

但是我注意到价值和当前的时间有关。


没有想太多,直接写,0分

然后发现输入方式不对……


改了之后只有25分


我知道wa是因为时间会影响价值,但不知道怎么做。

后来看了题解,发现我对01背包理解不够透彻
普通01背包做下来放入物品的顺序是1到n的
因为这个时候顺序没有关系,所以可以直接做
但是这道题后面放的物品价值小,所以价值有关系
所以就要提前排好序。
排序的依据就判断相邻两个物品先后放的价值,
然后化简可以推出一个式子。
这里其实是一个贪心。
然后就做01背包就好了

然后注意开long long 

#include<cstdio>
#include<algorithm>
#include<cstring>
#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;
}

 

posted @ 2018-09-08 11:00  Sugewud  阅读(130)  评论(0编辑  收藏  举报