您的位置:首页 > 其它

codeforces 366C C. Dima and Salad(dp)

2017-10-15 21:04 447 查看
这个题 想法还是不错的 首先我们要求 sum (a[i]) 的最大值.

我们发现,每一个a[i] ,b[i] 的范围都很小 ,这里面一定有阴谋 hhh

这样的话我们可以用一个数组 c[i] 记录每一个 a[i] - k * b[i] ; 当作每一个物品的体积, 然后因为每个物品只能被选一个,我们怎么控制呢 ?c[i] >= 0 的我们算一次 c[i] < 0 的我们算一次,对于这两种情况这样就可以了。 剩下的转移就是 0 1 背包 不过这个题貌似要写滚动数组。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

const int maxn = 10005;
const int INF = 1E9 + 7;

int dp1[maxn] = {0};
int dp2[maxn] = {0};
int a[maxn] = {0};
int b[maxn] = {0};
int c[maxn] = {0};
int n,k;

int main () {
ios_base :: sync_with_stdio(false);
cin >> n >> k;
for (int i = 1;i <= n; ++ i) cin >> a[i];
for (int i = 1;i <= n; ++ i) cin >> b[i],c[i] = a[i] - k * b[i];
for (int i = 0;i < maxn; ++ i) {
dp1[i] = dp2[i] = -INF;
}
dp1[0] = dp2[0] = 0;
for (int i = 1;i <= n; ++ i) {
if (c[i] >= 0) {
for (int j = maxn - 1;j >= c[i]; -- j) {
dp1[j] = max (dp1[j],dp1[j - c[i]] + a[i]);
}
}
}
for (int i = 1;i <= n; ++ i) {
if (c[i] < 0) {
c[i] = -c[i];
for (int j = maxn - 1;j >= c[i]; -- j) {
dp2[j] = max (dp2[j],dp2[j - c[i]] + a[i]);
}
}
}
int ans = -1;
for (int i = 0;i < maxn; ++ i) {
if (dp1[i] == 0 && dp2[i] == 0) continue;
if (dp1[i] >= 0 && dp2[i] >= 0) {
ans = max (ans,dp1[i] + dp2[i]);
}
}
cout << ans << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces dp