如果题目要求解一个线性规划问题,可能可以使用这个知识点。
以下面一个方程为例:
5x[1]+2x[2]+3x[3]<=60
10x[1]+5x[2]+4x[3]<=100
x[1]+6x[2]+7x[3]<=50
求x[1]+5x[2]+3x[3]的最大值
x[i]>=0
转化得到:
5x[1]+10x[2]+x[3]>=1
2x[1]+5x[2]+6x[3]>=5
3x[1]+4x[2]+7x[3]>=3
求60x[1]+100x[2]+50x[3]的最小值。
例题:
CF671D
此题可以使用线段树+dfs序或线段树合并解决,但是有更奇妙的方法。
题目要求使用m条从儿子->父亲的链覆盖整棵树,且边权和最小。
实际上可以设计个线性规划模型。
设有一颗树,1-2有边,1-3有边,3-4有边。
有3条链:1-2,1-4,3-4,权值为1,3,2
把每条链作为一个变量,每一条边作为一个方程。变量为x[1],x[2],x[3]。
可以设计出这个线性规划模型:
x[1]>=1
x[2]>=1
x[2]+x[3]>=1
x[i]>=0
最小化x[1]+3x[2]+2x[3]
补全方程:
x[1]+0x[2]+0x[3]>=1
0x[1]+x[2]+0x[3]>=1
0x[1]+x[2]+x[3]>=1
x[i]>=0
最小化x[1]+3x[2]+2x[3]
对偶一下:
x[1]<=1
x[2]+x[3]<=3
x[3]<=2
最大化x[1]+x[2]+x[3]
它的意义是:把每条链作为一个方程,把每条边作为一个变量,要求给每条边赋一个权值,使得每条链上的权值和<=它的代价,且让权值和最大。
从深到浅能选就选。用可并堆维护当前x->父亲能选多少个。选了以后就打一个标记表示堆内元素整体减去一个值。
当堆顶不在范围内就删除。
bzoj3118