标签:不可 背包问题 价格 元素 处理 他也 优惠 数据 订单
背包问题【DP】
01背包
f[j]=max(f[j],f[j-w[i]]+c[i]);
搬书【DP】
n^3枚举从哪一堆上选
f[a][b][c] = max(f[a-1][b][c]+w[1][a]*T,f[a][b-1][c]+w[2][b]*T,f[a][b][c-1]+w[3][c]*T);
排队问题(贪心策略明显)【反证法】
按时间从小到大排。
证明:若t[i]>t[j],交换i,j一定能得到更优的解
神牛果(贪心策略明显)【反证法】
排序,每次取出最大和最小的为一组。
修理牛棚(贪心策略明显)【倒推法】
初始为一整块木板,可以选择m-1个断点。
将断开的长度从大到小排。
删数(贪心策略明显)【倒推法】
因为一共选n-k个数,设当前为第i个,上次选了第L个
至少要留n-k-i个给后面,那么第i个即为min(a[L+1]~a[n-k-i+1])
(或者:从高位到低位遍历k次,如果数字递增则删最大的(最后一位);
否则删开始递减的第一个(左边第一个递减区间的第一位),比如123654798,就删掉6 )
调整法:列出不等式,交换等式两边得到贪心方案
奶酪工厂(贪心策略不明显)【调整法】
某周需要的奶酪一定在同一周生产,也就是说与奶酪订单需要量无关。
问题可以转化为当前周生产奶酪的最低价格。
设i<j<k,如果c[i]+(j-i)*s < c[j],则:
c[i]+(j-i)*s+(k-j)*s < c[j]+(k-j)*s
c[i]+(k-i)*s < c[j]+(k-j)*s
设第i周的最优生产时间为f[i],则一定有f[i] = f[i-1]或i
每次比较并记录当前周的生产时间即可。
堆积木【调整法】
没想出来
设当前最优的方案从下到上积木编号为1,2
则有f[1]-w[2] < f[2]-w[1]
f[1]+w[2] < f[2]+w[1]
即从下到上的顺序是按f+w从小到大排。
国王游戏【调整法】
设当前最优的方案从前到后编号为0,1,2(0为国王)
则max(a[0]/b[1],a[0]*a[1]/b[2]) < max(a[0]/b[2],a[0]*a[2]/b[1])
因为一定有a[0]*a[2]/b[1] > a[0]/b[1],a[0]*a[1]/b[2] > a[0]/b[2]
所以转化为 a[0]*a[1]/b[2] < a[0]*a[2]/b[1]
a[1]*b[1] < a[2]*b[2]
即按从前往后的顺序是按a*b从小到大排。
让步法:竞争公共资源时,尽量使剩余选择最大化 我瞎编的
智力大冲浪【让步法】
总钱数是一定的,问题转化为使扣去的钱最少。
按w从大到小排序。
检查1~t[i]是否有时间没有没占用,如果都被占了则要扣去w[i]的钱
如果有可选的,则尽量选择时间靠后的,给其他的留出前面的时间!
整数区间【让步法】
按右端点从小到大排序。这样右端点单调,即保证,在当前选取的整数序列a[]中,
若下一个区间不包含a[i],则一定不包含a[i-1],a[i-2]….
即最有可能被下一个区间包含的一定是最右边的数。
设当前已经选取的整数中,最右边的两个数为x,y。
检查x,y是否被当前区间包含;若都包含,则继续下一个区间;
若不包含x,包含y,则选择这个区间的右端点。
若都不包含,则选择最右的两个(右端点-1和右端点)。
这样选择出来的数是单调递增的,且尽量大,也就是被下一个区间包含的机会尽量大。
活动选择【让步法】
上一个活动结束的越早越好。
按右端点从小到大排序,能选则选。
雷达安装【让步法】
雷达的覆盖范围是一样的,
每个小岛可以被一定范围内的雷达覆盖到,可求出每个小岛可选的雷达区间。
转化为和整数区间类似的问题。
按右端点排序,设安装的雷达中最右的横坐标为x。
若x在这个小岛的区间内,则继续;否则选这个小岛的区间的右端点安装雷达。
晒衣服(贪心+桶)
因为每个单位时间所有衣服自然晒干1点,所以要使每个单位时间湿度最大的衣服湿度最小
所以烘干机给当前湿度最大的用就行了。
维护一个优先队列,元素为初始湿度,每次取出队首,把它减去B点湿度,再压回去。
当队首小于A*t时,说明已全部晾干
游戏通关(贪心+并查集)
这道题和智力大冲浪相同,只是将最小减少奖励改为最大增加奖励;
奖励从大到小排序,并且在可行区间内尽量往后放。
不过数据范围较大,如果暴力枚举1~t[i]大概会超时。
用并查集优化:把已占用的时间全部连起来,fa[x]-1即为可选的;
想要选择时间x时,若x可用,分别判断x-1、x+1是否也已被占用,被占用则与x连接;
若x不可用,则上一个可用的时间即为getfa(x)-1。
探险(贪心+堆)
油不花钱,油箱也没有容量上限,从起点到终点需要的油是一定的。
想要加油次数尽量少,就要每次加的油尽量多。按存油量大小维护优先队列。
在起点到终点的路上,一定会经历每一个加油站。
枚举每一个加油站,如果当前的总油量能到达,则可以在这里加油,把它加入优先队列。
如果不能到达,则在能加油的加油站中加最多的,即取出优先队列的队首,加入总油量,直到总油量能到达这个加油站为止。
若优先队列为空时也到不了则无解。
优惠券(贪心+堆)【调整法】
要买的最多,那一定是先买优惠券价最便宜的。
如果优惠券没用完,钱就花光了,当前买的书即为答案。
如果钱还有剩,那么对于剩下的n-k本书,
判断是用原价买它,或把另一本书的优惠券给它而另一本原件买比较便宜。
但是若枚举所有已经使用优惠券的书,时间复杂度显然不友好。
交换条件为c[j]+p[i] < c[i]+p[j],即p[i]-c[i] < p[j]-c[j]
因此,优先队列要维护的是:原价和优惠券价的差值,从小到大排。
每当对某本书使用优惠券时,把它的差值压入优先队列。
探讨人生(贪心+枚举)
这不是多重背包吗
贪心优化暴力…
因为只有两个人,所以暴力枚举探讨次数就可以了。
原来没给数据范围,所以我编了一个… √n可过。
剪枝:先swap一下,保证与A探讨单位时间经验更多。
为了使枚举的探讨次数控制在√n以内,需要判断一下:
若a>√n,则枚举次数一定小于√n,正常枚举与a探讨次数即可。
否则,枚举与B探讨次数。
因为与A探讨更优,即与A探讨b次优于与B探讨a次,
所以当枚举与B探讨次数大于等于a时,一定不如把其中的a次变成和A探讨。
所以最多只要枚举a次。
例题:数字游戏(贪心+DP)
贪心得到dp枚举顺序。
当m=n,即全选时,显然按b从大到小选。
m<n时,需要用dp解决,但策略是相同的,即把b从大到小排序。
设f[j]表示选j个数得到的最大价值。
状态转移方程:f[j] = max(f[j-1]+a[i]-b[i]*(j-1))
马步距离(贪心+搜索)
直接搜索会超时,考虑优化。
因为棋盘无限大,所以四个方向是一样的,也就是说可以任意进行对称。
为了方便,把s翻转到p的右下。
通过打表可以发现, p和s相距较远时,移动的方式只有从(x,y)到(x+1,y+2)或(x+2,y+1),
也就是一直向右下走就行了…
打出大概5,5的矩阵(不放心的话就多打点…),当距离差超出这个矩阵时,
取绝对值,令x,y>0,swap使x>y,将x-=2,y-=1。
当x,y进入矩阵时,直接返回答案即可。
不想打表的话,也可以把x,y缩小到一定范围内后进行bfs。
标签:不可 背包问题 价格 元素 处理 他也 优惠 数据 订单
原文地址:https://www.cnblogs.com/mogeko/p/11762212.html