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这时就是完全背包,完全背 ...
随机推荐
- 主机映射Linux虚拟机硬盘到本地
Windows7上面通过VMware装了一个ubuntu的虚拟机,为了方便在window下直接查看和编辑linux系统下的代码,就想着远程映射硬盘,把Ubuntu的硬盘映射到主机中. 硬盘映射需要Sa ...
- find命令和tar命令的使用
tar命令 tar -zcvf small.tar.gz small(目录名) (压缩) tar -zxvf small.tar.gz -C small(目录名) (解压到指定目录) find 命令 ...
- session保存用户信息
前台jsp-------------- <%@ page import="com.manager.form.User" %><%User user = reque ...
- 慕课网-Java入门第一季-6-9
来源:http://www.imooc.com/code/1571 所谓二维数组,可以简单的理解为是一种“特殊”的一维数组,它的每个数组空间中保存的是一个一维数组. 那么如何使用二维数组呢,步骤如下: ...
- js获取项目根目录的方法
getRootPath = function(){ //获取当前网址,如: http://localhost:8080/ems/Pages/Basic/Person.jsp var curWwwPat ...
- WM_GETMINMAXINFO消息 中结构体MINMAXINFO
MINMAXINFO* lpMMI lpMMI->ptMaxSize.x = 800; // 设置窗口最大化时的宽度 lpMMI->ptMaxSize.y = 600; // 设置窗口 ...
- python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
python Django教程 之 模型(数据库).自定义Field.数据表更改.QuerySet API 一.Django 模型(数据库) Django 模型是与数据库相关的,与数据库相关的代码 ...
- 阿里云 esc 云服务器无缘无故的一次/usr/bin 目录丢失导致整个服务无法启动 # ./shutdown.sh ./shutdown.sh: line 41: dirname:command not found cannot find /catalina.sh the find /catalina.sh The file is absent or does not have execute
总结上个星期服务器环境上的一个问题,一直再忙AR.防近视的项目没时间整理.刚好忙完项目认真回顾8月30发生的一个让人奇葩的问题. 早上把项目上的一些问题优化完,快到中午吃饭的时间频繁的启动导致/usr ...
- 将字母变为其下个字母(abc变为bcd)
题目描述 输入一行电报文字,将字母变成其下一字母(如'a'变成'b'--'z'变成'a'其它字符不变). 输入 一行字符 输出 加密处理后的字符 样例输入 a b 样例输出 b c#include & ...
- CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files 解决方案
1 设置c:windows\temp 目录访问权限 temp--> 属性-->安全-- > 添加network service -->并赋予其权限为 读 和 写--> 确 ...