题目链接 NYOJ747
【题意】
蚂蚁的难题(三)
时间限制:
2000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
蚂蚁终于把尽可能多的食材都搬回家了,现在开始了大厨计划。
已知一共有 n 件食材,每件食材有一个美味度 Ai 和新鲜度 Bi , 如果蚂蚁在第t时刻将第i样食材烹饪成功,则得到Ai-t*Bi 的美味指数,当然,用第i件食材做饭要花去 Ci 的时间。
众所周知,蚂蚁的厨艺不怎么样,所以他需要你设计做饭方案使得在时间 T 内完成的美味指数最大。-
输入
-
有多组测试数据。
第一行是两个正整数,表示蚂蚁的做饭时间T和食材个数n。(n<=50, 1<=T<=100000)。
接下来n行,每行有三个数,Ai,Bi,Ci。分别代表美味度、新鲜度和用该食材做饭花费的时间。(0<Ai,Bi,Ci<=100000).
输出
- 输出一个数字,表示最大美味指数 样例输入
-
6 1 200 5 1
样例输出
-
195
-
有多组测试数据。
【分析】
很像01背包,一开始知道需要先贪心排序,但是怎么也找不到如果排序,贪心还是太弱,后来看了出题人的博客才知道;需要用相邻的两个物品1和2;
然后分别写出1先做和2先做可以得到的最大价值,并且假设现在已经是T时刻:
如果1物品先做:A[1]-(P+C[1])*B[1]+A[2]-(P+C[1]+C[2])*B2;(1)
如果2物品先做:A[2]-(P+C[2])*B[2]+A[1]-(P+C[1]+C[2])*B1;(2)
则可以按照(1)>(2)来排序,化简(1)>(2)为C[2]*B[1]>C[1]*B[2];
接下来直接01背包就可以了
【AC代码】32ms
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 100001
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
struct NODE{
int a, b, c;
}p[51];
int ans, ch, dp[MAXN];
int in()
{
while((ch = getchar()) < '0' || '9' < ch);
ans = ch-'0';
while((ch = getchar()) >= '0' && '9' >= ch) ans = ans*10+ch-'0';
return ans;
}
inline bool cmp(const NODE& a, const NODE& b){return b.c*a.b>a.c*b.b;}
int main()
{
#ifdef SHY
freopen("e:\\1.txt","r",stdin);
#endif
int m, n;
while(~scanf("%d %d%*c", &m, &n))
{
int ans = 0;
for (int i = 0; i < n; i++)
{
p[i].a = in();
p[i].b = in();
p[i].c = in();
}
sort(p,p+n,cmp);
memset(dp,0,sizeof(dp));
for (int i = 0; i < n; i++)
{
for (int j = MIN(m,p[i].a/p[i].b); j >= p[i].c; j--)//剪枝,T<=A/B && T <= M
dp[j] = MAX(dp[j], dp[j-p[i].c]+p[i].a-j*p[i].b);
}
for (int i = 0; i <= m; i++)
ans = max(ans,dp[i]);
printf("%d\n", ans);
}
return 0;
}