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这时就是完全背包,完全背 ...
随机推荐
- 谈谈Java面向对象的三大特性
Java面向对象的三大特性就是指封装.继承.多态了. 一.封装: 概念:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. (举例:笔记本电脑就是一个封装体,Java语言中最小的封装体就是函数 ...
- 习课的视频播放器 video.js
jsp <%@ page language="java" contentType="text/html; charset=utf-8" pageEncod ...
- 使用struts通配符报错
报错截图如下: 主要原因是:对大小写敏感. struts.xml StudentAction.java jsp页面:(重点就是这里,锚里面需要特别注意,大小写应该与struts.xml里面的保持一致, ...
- 移动端网页fixed布局问题解决方案
问题说明 移动端web的footer常常设计为fixed布局,但是在页面键盘被拉起时fixed的布局会出现问题,自己试了下,在较低版本ios和部分安卓机上会有此问题.具体问题看图示: <body ...
- 中文api接口
http://www.bejson.com/knownjson/webInterface/
- 头像上传,拖拽,裁切 (非HTML5)版本
演示地址: http://codeman35.itongyin.com:19002/v2/web_demo.html 功能: 支持滚轴放大缩小,鼠标拖动,裁切可视区域,裁切和图片处理都是后端操作.
- 将对象的所有属性名放到一个数组中 || 获得对象的所有属性名 || return;不具有原子性 || 怎样自己制作异常|| 判断对象有没有某个属性 || 当传递的参数比需要的参数少的时候,没有的值会被赋予undefined || 获得函数实际传递的参数 || 怎么用函数处理一个对象 || 用一个名字空间定义一个模块所有的函数 || 给一个对象添加方法
获得对象的所有属性名 || 将对象o的所有属性名放到数组中 var o = {x:1,y:2,z:3}; var arr = []; var i = 0; for(arr[i++] in o){};/ ...
- $.getJSON在IE8下失效
$.getJSON("/Home/GetData?r=" + Math.random(), { ids: ids }, function(data) { //处理逻辑 }); 原因 ...
- 笔试常考的Java基础
1. Socket编程:ServerSocket (int port) :Creates a server socket, bound to the specified port. Socket(In ...
- python中string模块
>>> import string >>> string.ascii_letters 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL ...