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. 使用delphi+intraweb进行微信开发5—准备实现微信API,先从获取AccessToken开始

    在前4讲中我们已经使iw开发的应用成功和微信进行了对接,再接下来的章节中我们开始逐一尝试和实现微信的各个API,开始前先来点准备工作 首先需要明确的是,微信的API都是通过https调用实现的,分为p ...

  2. adb 命令集合

    1. adb shell 2. adb version 查看 adb 安装版本 3. adb start-server 启动服务 4. adb kill-server 杀死服务 5. adb get- ...

  3. sencha touch+phonegap+node.js打包

    这讲我们来讲解下如何使用phonegapa创建项目环境并通过她们将sencha touch打包成app,这里我们只讲解打包android的apk,打包ios的过程有点类似,但是需要在mac环境下,最后 ...

  4. Have Fun with Numbers及循环链表(约瑟夫问题)

    1. 循环链表(约瑟夫问题) https://github.com/BodhiXing/Data_Structure 2. Have Fun with Numbers https://pta.pate ...

  5. Eclipse+MinGW+Boost环境搭建

    一.编译 运行 .bat 生成bjam.exe 运行:bjam --build-type=complete toolset=gcc stage 二.配置 配置eclipse -L Path加入链接库位 ...

  6. flask + uwsgi 生产环境

    https://www.digitalocean.com/community/tutorials/how-to-deploy-flask-web-applications-using-uwsgi-be ...

  7. sybase ODBC驱动

    windows64位系统ODBC数据源管理器位置 64位 C:\Windows\System32\odbcad32.exe 32位 C:\Windows\SysWOW64\odbcad32.exe s ...

  8. archlinux配置答疑

    Q: chinese can not appear in my firefox and terminal rightly A: pacman -S wqy-microhei Q: install pi ...

  9. promise实例小球运动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. FileInputStream、FileReader、FileInputStream、FileWriter使用小结

    本文是基于Linux环境运行,读者阅读前需要具备一定Linux知识 InputStream包含如下三个方法: int read():从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转化为i ...