2017山东夏令营测验 D5T1 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

小菜一碟的背包
题目描述
有n头奶牛,每头奶牛有食量w[i]和产奶量v[i],每天能够提供W千克草料。选取奶牛使产奶总量尽可能大,问最大是多少。
输入格式
第一行两个整数 ,表示奶牛的数量和每天最多能提供的草
接下来i行,每行两个整数,第i行表示第I头奶牛的产奶量和食量
输出格式
仅一行,输出一个整数,表示每天最大的总产奶量
输入样例
8 40
10 9
12 11
11 12
10 10
8 11
7 9
8 10
9 10
输出样例
41
限制与约定
对于所有数据,1 ≤ n ≤ 100,1 ≤ wi,W ≤ 10^9,1 ≤ vi ≤ 10^7,w1 ≤ wi ≤ w1 + 3.

分析:

并不是小菜一碟...

由于W的范围太大,不能用常规的01背包来做。

注意到w[]的波动范围很小,所以我们可以将所有的w减去一个基数,f[i][j][k]表示前i头奶牛中选取j头,其食量(减去基数之后的)和为k。

逆向转移。状态转移方程:f[i][j][k] = max(f[i+1][j][k],f[i+1][j+1][k+w[i+1]]+v[i+1]);

AC代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4
 5 const int MAXN = 105;
 6
 7 inline void read(int &x)
 8 {
 9     char ch = getchar(),c = ch;x = 0;
10     while(ch < ‘0‘ || ch > ‘9‘) c = ch,ch = getchar();
11     while(ch >= ‘0‘ && ch <= ‘9‘) x = (x<<1)+(x<<3)+ch-‘0‘,ch = getchar();
12     if(c == ‘-‘) x = -x;
13 }
14 long long f[MAXN][MAXN][305];
15 bool vis[MAXN][MAXN][305];
16 //choose j cows sum value
17 int w[MAXN],v[MAXN],n,W;
18 int mn = 2e9;
19
20 int dp(int i,int j,int k)
21 {
22     if (1LL*j*mn+k>W) return -2e9;//装不下了
23     if(i == n)    return 0;//已经全部尝试完
24     if(vis[i][j][k]) return f[i][j][k];
25     vis[i][j][k] = true;
26     return f[i][j][k] = std::max(dp(i+1,j,k),dp(i+1,j+1,k+w[i+1])+v[i+1]);
27 }
28
29 int main()
30 {
31     read(n),read(W);
32     for(int i = 1;i <= n;++ i)
33         read(v[i]),read(w[i]),mn = std::min(w[i],mn);
34     mn --;//mn就是基准数
35     for(int i = 1;i <= n;++ i)
36         w[i] -= mn;
37     printf("%d\n",dp(0,0,0));
38 }
时间: 2024-11-07 02:27:15

2017山东夏令营测验 D5T1 题解的相关文章

2017 百度之星 资格赛 题解

百度之星 2017 资格赛 题解(原创)(2~5题 第一题方法是错的 第二题数据太水 并不会正解) 转载请注明出处http://www.cnblogs.com/nflslzt/p/7302377.html (题目在HDU上可以找到) 1001 度度熊保护村庄 题意 给你两个点集,A和B,问你在B中最少选取多少个点,使得B中剩余点的凸包能将A的凸包完全包住 数据范围 A,B中有500个点 多测 (n^3会超时) 想法 首先把两个点集的凸包求出来 贪心:B的凸包内部点全部可以去掉 可能(就)是伪证:

2017省夏令营Day7 【快速幂,筛法,矩阵快速幂,线段树】

题解:首先,我们可以得到一个规律:经过2次变换后,a和b的值都分别乘2了,所以只要用快速幂就能过啦,但是,要特判n为0的情况. 代码如下: 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define Mod 1000000007 5 using namespace std; 6 long long a,b,n,ans1,ans2; 7 long long power(long long x)

2017省夏令营Day6 【dp】

题解:区间dp,f[i][j]表示区间[i,j]的狼全部消灭的最小代价,设k为i.j间任意一点(i<=k<=j),且第k只狼被最后消灭,显然,区间总代价即可被我们划分成[i,k-1]和[k+1,j]两部分,我们可以假设他们已知,于是求得两区间代价和再加上消灭第k只狼的代价就能求得区间[i,j]的总代价. 状态转移方程:f[i][j]=f[i][k-1]+f[k+1][i]+a[k]+b[i-1]+b[j+1]. PS:注意初始化时i要从0开始枚举,且若j<i时f值为0. 代码如下: 1

2017省夏令营Day8 【bfs,并查集】

题解:出题人丧心病狂~ 对于这道题,我们对每一个内应节点bfs,并用并查集维护,如果s和t联通,输出答案并break. PS几个小细节:①对于每个内应dis=0,为了保证不会对答案产生影响,我们在每2个节点中插入一个新的节点即可: ②因为加入新节点,数组要开大些,否则会炸. 代码如下: 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define Max 2020304 5 using nam

loj6102 「2017 山东二轮集训 Day1」第三题

传送门:https://loj.ac/problem/6102 [题解] 贴一份zyz在知乎的回答吧 https://www.zhihu.com/question/61218881 其实是经典问题 # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> using namespace std; typedef long long ll; typed

2017福建夏令营Day1(数据结构)

工作团队 [问题描述] 一家公司有??名员工,刚开始每个人单独构成一个工作团队. 有时一项工作仅凭一个人或一个团队难以完成,所以公司会让某两个 人所在的团队合并. 但有的工作属于闷声大发财类型的,不适合多人做,所以公司有时也 会让一个人从他当前所在的团队中分离出来,构成单独的团队. 公司也要对当前团队的情况进行了解,所以他们也会询问一些问题, 比如某两个人是否属于同一工作团队,某个人所在的团队有多少个人,或 者当前一共有多少个工作团队. 作为该公司的软件服务商,你的任务便是实现一个实时的操作和查

2017山东注册会计师报名时间一般是什么时候

2017注册会计师报名时间和考试时间是什么时候呢,大家都知道2016年注会报名时间与考试时间于今年3月已公布.而2017年注册会计师报名时间和考试时间什么时候呢,大家不用着急,小编整理2016注册会计师报名时间和考试时间解析,供大家参考,请安心复习备考今年考试. 考试科目和考试范围 专业阶段考试科目:会计.审计.财务成本管理.公司战略与风险管理.经济法.税法. 专业阶段考试报名人员可以同时报考6个科目,也可以选择报考部分科目. 综合阶段考试科目:职业能力综合测试(试卷一.试卷二).考试范围:<注

2017 ACM/ICPC 广西邀请赛 题解

题目链接  Problems HDOJ上的题目顺序可能和现场比赛的题目顺序不一样, 我这里的是按照HDOJ的题目顺序来写的. Problem 1001 签到 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) typedef long long LL; LL n, f[31]; int ans; int main(){ f[1] = 1LL; fo

2017 09 17 测验解题报告

预计分数 100+100+20 >=220 实际分数 100+50+20 =170 T1 :100 巧克力棒(chocolate)Time Limit:1000ms Memory Limit:64MB题目描述 LYK 找到了一根巧克力棒,但是这根巧克力棒太长了,LYK 无法一口吞进去.具体地,这根巧克力棒长为 n,它想将这根巧克力棒折成 n 段长为 1 的巧克力棒,然后慢慢享用. 它打算每次将一根长为 k 的巧克力棒折成两段长为 a 和 b 的巧克力棒,此时若 a=b,则 LYK 觉得它完成了一