题目链接:http://codeforces.com/problemset/problem/366/C
题意:在一个冰箱里有n种水果,并且这些水果每一种都有一个美味度和一个卡路里的属性, 小明要从这些水果中选出来一些做一个水果沙拉, 并且要求他的水果沙拉的美味度之和是卡路里和的k倍,问小明是否可以做出这么一个水果沙拉,若不能输出-1,否则输出符合要求的最大的美味值之和。
思路:我们将物品做一个变形,重量为a[i]-b[i]*k,收益是a,那么我们只需要对重量为正的做一遍背包,对质量为负的取绝对值做一遍背包,然后重量相等的背包的收益之和就是当前重量下的最大收益.
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e4 + 5;
int n, k;
int a[maxn], b[maxn], c[maxn], dp1[maxn], dp2[maxn];
int main()
{
scanf("%d%d", &n, &k);
memset(dp1, -0x3f, sizeof(dp1));
memset(dp2, -0x3f, sizeof(dp2));
for(int i = 1;i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= n; i++)
scanf("%d", &b[i]);
for(int i = 1; i <= n; i++)
{
c[i] = b[i]*k - a[i];
}
dp1[0] = dp2[0] = 0;
for(int i = 1; i <= n; i++)
{
if(c[i] >= 0)
{
for(int v = 10000; v >= c[i]; v--)
dp1[v] = max(dp1[v], dp1[v-c[i]]+a[i]);
}
else
{
for(int v = 10000; v >= -c[i];v--)
dp2[v] = max(dp2[v], dp2[v+c[i]]+a[i]);
}
}
int ans = 0;
for(int i = 0; i < 10005; i++)
if(dp1[i] != -1 && dp2[i] != -1)
{
ans = max(ans, dp1[i] + dp2[i]);
}
if(ans == 0)
cout << -1 << endl;
else
cout << ans << endl;
return 0;
}
解决Codeforces上的水果沙拉问题,通过将物品转化为特定属性,利用动态规划进行两遍背包操作,找到满足美味度与卡路里比值条件的最大美味值之和。
1690

被折叠的 条评论
为什么被折叠?



