C. Dima and Salad 背包好题
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 背包好题的更多相关文章
- 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 ...
- 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 ...
- Dima and Salad(完全背包)
Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- CF#214 C. Dima and Salad 01背包变形
C. Dima and Salad 题意 有n种水果,第i个水果有一个美味度ai和能量值bi,现在要选择部分水果做沙拉,假如此时选择了m个水果,要保证\(\frac{\sum_{i=1}^ma_i}{ ...
- CF Dima and Salad 01背包
C. Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- codeforces-214(Div. 2)-C. Dima and Salad+DP恰好背包花费
codeforces-214(Div. 2)-C. Dima and Salad 题意:有不同的沙拉,对应不同的颜值和卡路里,现在要求取出总颜值尽可能高的沙拉,同时要满足 解法:首先要把除法变成乘法, ...
- Codefroces 366 C Dima and Salad(dp)
Dima and Salad 题意:一共有n种水果,每种水果都有一个ai, bi,现求一个最大的ai总和,使得ai之和/对应的bi之和的值等于K. 题解:将bi转换成偏移量,只要偏移到起点位置,就代表 ...
- HDU 1712 ACboy needs your help (分组背包模版题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1712 有n门课,和m天时间.每门课上不同的天数有不同的价值,但是上过这门课后不能再上了,求m天里的最大 ...
- hdu 2191 珍惜现在,感恩生活 多重背包入门题
背包九讲下载CSDN 背包九讲内容 多重背包: hdu 2191 珍惜现在,感恩生活 多重背包入门题 使用将多重背包转化为完全背包与01背包求解: 对于w*num>= V这时就是完全背包,完全背 ...
随机推荐
- 使用delphi+intraweb进行微信开发5—准备实现微信API,先从获取AccessToken开始
在前4讲中我们已经使iw开发的应用成功和微信进行了对接,再接下来的章节中我们开始逐一尝试和实现微信的各个API,开始前先来点准备工作 首先需要明确的是,微信的API都是通过https调用实现的,分为p ...
- adb 命令集合
1. adb shell 2. adb version 查看 adb 安装版本 3. adb start-server 启动服务 4. adb kill-server 杀死服务 5. adb get- ...
- sencha touch+phonegap+node.js打包
这讲我们来讲解下如何使用phonegapa创建项目环境并通过她们将sencha touch打包成app,这里我们只讲解打包android的apk,打包ios的过程有点类似,但是需要在mac环境下,最后 ...
- Have Fun with Numbers及循环链表(约瑟夫问题)
1. 循环链表(约瑟夫问题) https://github.com/BodhiXing/Data_Structure 2. Have Fun with Numbers https://pta.pate ...
- Eclipse+MinGW+Boost环境搭建
一.编译 运行 .bat 生成bjam.exe 运行:bjam --build-type=complete toolset=gcc stage 二.配置 配置eclipse -L Path加入链接库位 ...
- flask + uwsgi 生产环境
https://www.digitalocean.com/community/tutorials/how-to-deploy-flask-web-applications-using-uwsgi-be ...
- sybase ODBC驱动
windows64位系统ODBC数据源管理器位置 64位 C:\Windows\System32\odbcad32.exe 32位 C:\Windows\SysWOW64\odbcad32.exe s ...
- archlinux配置答疑
Q: chinese can not appear in my firefox and terminal rightly A: pacman -S wqy-microhei Q: install pi ...
- promise实例小球运动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- FileInputStream、FileReader、FileInputStream、FileWriter使用小结
本文是基于Linux环境运行,读者阅读前需要具备一定Linux知识 InputStream包含如下三个方法: int read():从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转化为i ...