背包与贪心
来源:互联网 发布:加工中心编程第一步 编辑:程序博客网 时间:2024/05/16 17:03
背包问题最经典的就是01背包。
n个物品,有体积 w 和价值 v 两种属性,选择一部分填充容量为 m 的背包(可以不填满),求能获得的最大价值。
其实分析下来,动态转移方程就是 f[i][v]=max{f[i-1][v], f[i-1][v-c[i]]+w[i]} ,优化后就是 f[v]=max{f[v], f[v-c[i]]+w[i]} (第二重for循环从m -> v[i],为了不更新i-1层的状态)
这个状态转移方程就会一个贪心过程,不断的用第i个物品更新每个f[j]的值,找到最大的f[j],最终的结果就是最大值。
其实背包除了不一定恰好装满,恰好装满,还有大于等于背包的容量这种状态。像这种大于背包容量的最优解,不会求最大值(求最大值可以一直贪,无穷大),会求大于背包容量的最小花费(中文其实挺好玩的,求最大就说获得的价值,求最小就说是花费),这是一个零界点,具有最优性质在里面,所以用贪心去优化背包。
看一道2017年百度之星的题:
度度熊与邪恶大魔王
对于每组测试数据,输出最小的晶石消耗数量,如果不能击败所有的怪兽,输出-1
这是一道完全背包,但是是n个背包,怪兽的生命力不同,防御值也不同,所以没有办法很好的去建立一个模型。
但是生命值1000种,防御值为10种,一共是10000种怪兽,我们求出这10000种怪兽的花费,在乘以该种类怪兽的数量,累加就是答案。这题的极限应该是O(1e9),但是数据应该不卡时间,所以200ms多就过了。
首先对m种技能进行排序(贪心策略),按防御力从小到大进行排序,防御力相同,花费大的在前(从劣往优排序),两重for,枚举怪物的种类,然后用m种物品更新最小花费。代码如下:
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#define LL long long#define P pair<int,int>using namespace std;const int maxn=1e5+100,maxm=1e4+10;int a[maxn],b[maxn];LL f[maxm];P c[maxm];int n,m,ma,mb;namespace std{bool operator < (const pair<int,int> &t,const pair<int,int> &s){ return t.second==s.second?(t.first>s.first):(t.second<s.second);}}LL solve(){ int t=1; for(int i=2; i<=m; ++i) { while(t>0&&c[t].first>c[i].first) --t; c[++t]=c[i]; } LL ans=0; for(int i=0; i<=mb; ++i) { for(int j=1; j<=ma; ++j) { f[j]=1ll*j*c[t].first; for(int k=1; k<=t; ++k) if(c[k].second>i) f[j]=min(f[j],f[max(0,j+i-c[k].second)]+c[k].first); } for(int j=1; j<=n; ++j) if(b[j]==i) ans+=f[a[j]]; } return ans;}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { ma=0,mb=0; for(int i=1; i<=n; ++i) { scanf("%d%d",&a[i],&b[i]); if(a[i]>ma) ma=a[i]; if(b[i]>mb) mb=b[i]; } for(int i=1; i<=m; ++i) scanf("%d%d",&c[i].first,&c[i].second); sort(c+1,c+m+1); if(c[m].second<=mb) { printf("-1\n"); continue; } /* for(int i=1;i<=m;++i) printf("%d %d\n",c[i].first,c[i].second); */ printf("%I64d\n",solve()); } return 0;}
阅读全文
0 0
- 背包与贪心
- 01背包与贪心的区别
- 算法设计与分析 普通背包 贪心
- 【算法】贪心算法之背包与装箱问题
- 贪心算法与活动选择问题和背包问题
- 算法分析与设计-15-背包问题的贪心算法
- 算法与数据结构-贪心算法及背包问题解决
- 浅谈动规贪心 与0-1背包和分数背包问题
- 背包问题--贪心
- 贪心算法 - 背包问题
- 贪心_01背包
- 贪心背包问题
- hdu2159(贪心+01背包)
- 饭卡(poj2546,贪心+背包)
- HDU1009-贪心-部分背包
- 贪心法-背包问题
- 【贪心+背包】【HDU2546】【饭卡】
- 贪心+背包详解
- 欢迎使用CSDN-markdown编辑器
- 并查集
- 从零到一学Maven——依赖范围及传递依赖
- MyISAM和InnoDB的区别
- 编一个C函数,子串在主串中出现多少次
- 背包与贪心
- Spring 与 SpringMVC Bean重复扫描问题
- java中的this和super
- 域名解析
- 天气晴朗的魔法 51Nod
- 一种排序 (南阳理工oj 题目8)
- 汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp这些都是什么意思啊?
- 文本内容相加
- 安卓四种点击事件类型总结