http://codeforces.com/contest/366/problem/C

在n个物品中选出若干个,使得sum(a[i]) = k * sum(b[i])

把问题转化一下就是,求sum(a[i] - k * b[i]) = 0的最大的a[i],这个时候已经把a[i]作为价值了

那么怎么去求呢?

一开始因为a[i] - k * b[i]有负数,那么需要fix值,fix = 1000

我只设了dp[v]表示产生这个和值时的最大价值。那么如果能产生这个v值,就需要这个v值能整除fix。因为sigma(a[i] - k * b[i])=0

那么这个v值其实就是若干个fix值相加而已。比如-1,fix后是999。。1,fix后是1001,相加是2000

所以只有v % fix == 0的才能作为贡献。但是有bug。因为你不知道它是多少个数相加得到的v。如果是5个数得到的v,那么需要这个v要整除5 * fix才可以,所以我就用了dp[i][j]表示选了i个数产生j的最大价值。但是这样转移是1e9的,但是水过去了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e2 + ;
int a[maxn], b[maxn];
struct node {
int w, val;
}c[maxn];
const int fix = ;
int dp[ + ][ * + ];
void work() {
int n, k;
cin >> n >> k;
int tot = ;
for (int i = ; i <= n; ++i) cin >> a[i];
for (int i = ; i <= n; ++i) {
cin >> b[i];
c[i].w = a[i] - k * b[i] + fix;
c[i].val = a[i];
tot += c[i].w;
}
memset(dp, -0x3f, sizeof dp);
// cout << -inf << endl;
cout << dp[][] << endl;
dp[][] = ;
for (int i = ; i <= n; ++i) {
for (int j = i; j >= ; --j) {
for (int k = tot; k >= c[i].w; --k) {
dp[j][k] = max(dp[j][k], dp[j - ][k - c[i].w] + c[i].val);
}
}
}
int ans = -;
for (int i = ; i <= n; ++i) {
for (int j = i * fix; j <= tot; j += fix) {
ans = max(ans, dp[i][j]);
}
}
cout << ans << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
IOS;
work();
return ;
}

所以这个是二维费用背包问题。

5 9
100 100 100 100 100
100 100 100 100 100

然后这题的正解因该是,分开dp,就是一样的转移问题是a[i] - k * b[i]

然后这些东西有正有负,那么就分开吧,dpup[v]表示整数那堆数,产生v这个数字的最大价值。

那么需要dpup[v] + dpdown[v]

注意有0的情况,0要单独处理一下,因为可能dpup[0]有值,但是dpdown[0]是-inf。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e2 + ;
int a[maxn];
int b[maxn];
int c[maxn];
int dpup[ * + ];
int dpdown[ * + ];
void work() {
int n, k;
cin >> n >> k;
int tans = ;
int tot = * ;
for (int i = ; i <= n; ++i) {
cin >> a[i];
}
for (int i = ; i <= n; ++i) {
cin >> b[i];
c[i] = a[i] - k * b[i];
if (c[i] == ) {
tans += a[i];
}
}
memset(dpup, -0x3f, sizeof dpup);
memset(dpdown, -0x3f, sizeof dpdown);
// cout << dpup[1] + dpdown[1] << endl;
dpup[] = dpdown[] = ;
for (int i = ; i <= n; ++i) {
// if (c[i] == 0) continue;
if (c[i] > ) {
for (int j = tot; j >= c[i]; --j) {
dpup[j] = max(dpup[j], dpup[j - c[i]] + a[i]);
}
} else {
c[i] = -c[i];
for (int j = tot; j >= c[i]; --j) {
dpdown[j] = max(dpdown[j], dpdown[j - c[i]] + a[i]);
}
}
}
int ans = -;
for (int i = ; i <= tot; ++i) {
ans = max(ans, dpup[i] + dpdown[i]);
}
if (tans != ) ans = max(tans, ans);
cout << ans << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
IOS;
work();
return ;
}

C. Dima and Salad 背包好题的更多相关文章

  1. Codeforces Round #214 (Div. 2) C. Dima and Salad 背包

    C. Dima and Salad   Dima, Inna and Seryozha have gathered in a room. That's right, someone's got to ...

  2. Codeforces Round #214 (Div. 2) C. Dima and Salad (背包变形)

    C. Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  3. Dima and Salad(完全背包)

    Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  4. CF#214 C. Dima and Salad 01背包变形

    C. Dima and Salad 题意 有n种水果,第i个水果有一个美味度ai和能量值bi,现在要选择部分水果做沙拉,假如此时选择了m个水果,要保证\(\frac{\sum_{i=1}^ma_i}{ ...

  5. CF Dima and Salad 01背包

    C. Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  6. codeforces-214(Div. 2)-C. Dima and Salad+DP恰好背包花费

    codeforces-214(Div. 2)-C. Dima and Salad 题意:有不同的沙拉,对应不同的颜值和卡路里,现在要求取出总颜值尽可能高的沙拉,同时要满足 解法:首先要把除法变成乘法, ...

  7. Codefroces 366 C Dima and Salad(dp)

    Dima and Salad 题意:一共有n种水果,每种水果都有一个ai, bi,现求一个最大的ai总和,使得ai之和/对应的bi之和的值等于K. 题解:将bi转换成偏移量,只要偏移到起点位置,就代表 ...

  8. HDU 1712 ACboy needs your help (分组背包模版题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1712 有n门课,和m天时间.每门课上不同的天数有不同的价值,但是上过这门课后不能再上了,求m天里的最大 ...

  9. hdu 2191 珍惜现在,感恩生活 多重背包入门题

    背包九讲下载CSDN 背包九讲内容 多重背包: hdu 2191 珍惜现在,感恩生活 多重背包入门题 使用将多重背包转化为完全背包与01背包求解: 对于w*num>= V这时就是完全背包,完全背 ...

随机推荐

  1. pacman -Syu : key could not be looked up remotely.

    # sudo pacman -Syu...error: key "5F702428F70E0903" could not be looked up remotelyerror: r ...

  2. Javascirpt中创建对象的几种方式

    js是一种动态语言,即js的对象创建好之后可以随意修改,因此JS对象的面向对象编程部分更可以说是通过JS的怪异特性来模拟Java这类的面向对象编程的.下面首先讨论几种创建对象的方式: 1. 工厂模式创 ...

  3. APNS 服务推送通知

    1. 将app注册notification里面, 并从APNS上获取测试机的deviceToken. - (BOOL)application:(UIApplication *)application ...

  4. js table的笔记,实现添加 td,实现搜索功能

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  5. STL学习 - map

    C++中map容器提供一个键值对容器,map与multimap差别仅仅在于multiple允许一个键对应多个值. 一.map的说明    1   头文件 #include <map> 2  ...

  6. 用adox 取 access 自增列

    百度很久 最后在 (.NET2.0下用ADOX动态创建ACCESS数据库(C#)) http://blog.csdn.net/black4371/article/details/4423739 找到了 ...

  7. R12将银行和分行都使用TCA管理

    R12将银行和分行都使用TCA管理,后台保存在HZ_PARTIES . 银行帐号:如果是付款或者是收款(本公司的帐号,内部帐号),都保存在ce_bank_accounts,ce_bank_acct_u ...

  8. spring quartz 定时器时间格式设置

    "0/10 * * * * ?" 10秒执行一次 "0 0 12 * * ?"每天中午十二点触发"0 15 10 ? * *"每天早上10: ...

  9. 一种table超出高度自动出滚动条的解决方案

    在日常的开发过程中,我们可能会遇到这样一种需求,在指定高度内显示table,超过高度时表格出滚动条. 让我们带着这个问题,一起来探讨吧! <!DOCTYPE html> <html ...

  10. prolog 内部谓词

    内部谓词 和其他语言一样,prolog也提供一些基本的输入输出函数. 内部谓词是指已经在prolog中事先定义好的谓词,在内存中的动态数据库中是没有内部谓词子句的.(当我们运行某个.pl 文件的时候, ...